Console.WriteLine("***** Fun with Class Types *****\n");
// Ошибка на этапе компиляции! Забыли использовать new для создания объекта!
Car myCar;
myCar.petName = "Fred";
Чтобы корректно создать объект с применением ключевого слова
new
, можно определить и разместить в памяти объект
Car
в одной строке кода:
Console.WriteLine("***** Fun with Class Types *****\n");
Car myCar = new Car;
myCar.petName = "Fred";
В
качестве альтернативы определение и размещение в памяти экземпляра класса может осуществляться в отдельных строках кода:
Console.WriteLine("***** Fun with Class Types *****\n");
Car myCar;
myCar = new Car;
myCar.petName = "Fred";
Здесь первый оператор кода просто объявляет ссылку на определяемый объект типа
Car
. Ссылка будет указывать на действительный объект в памяти только после ее явного присваивания.
В любом случае к настоящему моменту мы имеем простейший класс, в котором определено несколько элементов данных и ряд базовых операций. Чтобы расширить функциональность текущего класса
Car
, необходимо разобраться с ролью конструкторов.
Понятие конструкторов
Учитывая наличие у объекта состояния (представленного значениями его переменных-членов), обычно желательно присвоить подходящие значения полям объекта перед тем, как работать с ним. В настоящее время класс
Car
требует присваивания значений полям
petName
и
currSpeed
по отдельности. Для текущего примера такое действие не слишком проблематично, поскольку открытых элементов данных всего два. Тем не менее, зачастую класс содержит несколько десятков полей, с которыми надо что-то делать. Ясно, что было бы нежелательно писать 20 операторов инициализации для всех 20 элементов данных.
К счастью, язык C# поддерживает использование конструкторов, которые позволяют устанавливать состояние объекта в момент его создания. Конструктор — это специальный метод класса, который неявно вызывается при создании объекта с применением ключевого слова new. Однако в отличие от "нормального" метода конструктор никогда не имеет возвращаемого значения (даже
void
) и всегда именуется идентично имени класса, объекты которого он конструирует.
Роль стандартного конструктора
Каждый класс C# снабжается "бесплатным" стандартным конструктором, который в случае необходимости может быть переопределен. По определению стандартный конструктор никогда не принимает аргументов. После размещения нового объекта в памяти стандартный конструктор гарантирует установку всех полей данных в соответствующие стандартные значения (стандартные значения для типов данных C# были описаны в главе 3).
Если вас не устраивают такие стандартные присваивания, тогда можете переопределить стандартный конструктор в соответствии со своими нуждами. В целях иллюстрации модифицируем класс C# следующим образом:
class Car
{
// 'Состояние' объекта Car.
public string petName;
public int currSpeed;
// Специальный стандартный конструктор.
public Car
{
petName = "Chuck";
currSpeed = 10;
...
}
В
данном случае мы заставляем объекты
Car
начинать свое существование под именем
Chuck
и со скоростью 10 миль в час. Создать объект
Car
со стандартными значениями можно так:
Console.WriteLine("***** Fun with Class Types *****\n");
// Вызов стандартного конструктора.
Car chuck = new Car;
// Выводит строку "Chuck is going 10 MPH."
chuck.PrintState;
...
Определение специальных конструкторов
Обычно помимо стандартного конструктора в классах определяются дополнительные конструкторы. Тем самым пользователю объекта предоставляется простой и согласованный способ инициализации состояния объекта прямо во время его создания. Взгляните на следующее изменение класса
Car
, который теперь поддерживает в совокупности три конструктора:
class Car
{
// 'Состояние' объекта Car.
public string petName;
public int currSpeed;
// Специальный стандартный конструктор.
public Car
{
petName = "Chuck";
currSpeed = 10;
}
// Здесь currSpeed получает стандартное значение для типа int (0).
public Car(string pn)
{
petName = pn;
}
// Позволяет вызывающему коду установить полное состояние объекта Car.
public Car(string pn, int cs)
{
petName = pn;
currSpeed = cs;
}
...
}
Имейте в виду, что один конструктор отличается от другого (с точки зрения компилятора С#) числом и/или типами аргументов. Вспомните из главы 4, что определение метода с тем же самым именем, но разным количеством или типами аргументов, называется перегрузкой метода. Таким образом, конструктор класса
Car
перегружен, чтобы предложить несколько способов создания объекта во время объявления. В любом случае теперь есть возможность создавать объекты
Car
, используя любой из его открытых конструкторов. Вот пример:
Console.WriteLine("***** Fun with Class Types *****\n");
// Создать объект Car по имени Chuck со скоростью 10 миль в час.
Car chuck = new Car;
chuck.PrintState;
// Создать объект Car по имени Mary со скоростью 0 миль в час.
Car mary = new Car("Mary");
mary.PrintState;
// Создать объект Car по имени Daisy со скоростью 75 миль в час.