- •Классы и структуры
- •Функции-члены
- •Передача параметров в методы
- •Параметры ref
- •Параметры out
- •Свойства
- •Свойства, доступные только для чтения и только для записи
- •Модификаторы доступа для свойств
- •Автоматически реализуемые свойства
- •Замечание о встраивании
- •Индексаторы
- •Тип_элемента this[int индекс]
- •Листинг 1.
- •Листинг 2.
- •Листинг 3.
- •Листинг 4.
- •Конструкторы
- •Статические конструкторы
- •Вызов одних конструкторов из других
- •Поля readonly
- •Анонимные типы
- •Структуры
- •Структуры это типы значений
- •Структуры и наследование
- •Конструкторы структур
- •Частичные классы
- •Статические классы
- •Класс Object
- •Методы System.Object
- •Метод ToString()
- •Расширяющие методы
Конструкторы
Синтаксис объявления базовых конструкторов выглядит как объявление метода, который имеет то же имя, что и включающий его класс, и не имеет никакого типа возврата:
public class MyClass i
{
public MyClass ()
{
}
// остаток определения класса
Предусматривать конструктор в классе не обязательно. И до сих пор это не делалось ни в одном из приведенных примеров. В общем случае, если никакого конструктора не определяется, то компилятор просто создаст конструктор по умолчанию "за кулисами". Это будет конструктор очень обобщенного вида, который просто инициализирует все поля-члены, обнуляя их (null-ссылки для ссылочных типов, 0 для числовых типов и false для булевских). Часто это вполне адекватно; если же нет, то придется написать свой собственный конструктор.
Конструкторы подчиняются тем же правилам перегрузки, что и обычные методы (т.е. можно определять столько перегрузок конструктора, сколько необходимо, при условии, что они будут отличаться сигнатурой):
public MyClass () // конструктор без параметров
{
//код конструктора
}
public MyClass(int number) // другая перегрузка
{
//код конструктора
}
Однако обратите внимание, что если вы применяете любой конструктор с параметрами, то в этом случае компилятор не генерирует никакого конструктора по умолчанию. Такой конструктор генерируется только тогда, когда ни одного конструктора явно не определено. В следующем примере, поскольку определен конструктор с одним параметром, компилятор предполагает, что это единственный конструктор, который вы хотите сделать доступным, а потому не применяет никакого другого:
public class MyNumber
{
private int number;
public MyNumber(int number)
{
this.number = number;
}
}
Этот код также иллюстрирует типичное использование ключевого слова this для того, чтобы отличать поля класса от параметров с теми же именами. Теперь, если попытаться создать экземпляр класса MyNumber с помощью конструктора без параметров, возникнет ошибка компиляции:
MyNumber numb = new MyNumber () ; //вызовет ошибку при компиляции
Следует упомянуть также, что конструкторы можно объявлять приватными или защищенными так, что они будут невидимыми коду других классов:
public class MyNumber
{
private int number;
private MyNumber(int number) // другая перегрузка
{
this.number = number;
}
}
Этот пример на самом деле не определяет никакого общедоступного или даже защищенного конструктора для MyNumber. Это делает невозможным создание экземпляра данного класса внешним кодом с помощью операции new (хотя можно написать общедоступное статическое свойство или метод, в котором будет создаваться экземпляр класса). Это удобно в двух ситуациях:
-
если класс служит лишь контейнером для некоторых статических членов или свойств, а потому его экземпляры никогда не создаются;
-
если необходимо, чтобы экземпляры класса создавались только вызовом некоторой статической функции-члена (так называемый подход "фабрик классов" к созданию объектов).