Шрифт:
Интервал:
Закладка:
На заметку! Поля данных класса редко (если вообще когда-нибудь) должны определяться как открытые. Чтобы обеспечить целостность данных состояния, намного лучше объявлять данные закрытыми (private) или возможно защищенными (protected) и разрешать контролируемый доступ к данным через свойства (как будет показано далее в главе). Тем не менее, для максимального упрощения первого примера мы определили поля данных как открытые.
После определения набора переменных-членов, представляющих состояние класса, следующим шагом в проектировании будет установка членов, которые моделируют его поведение. Для этого примера в классе Car определены методы по имени SpeedUp() и PrintState(). Модифицируйте код класса Car следующим образом:
class Car
{
// 'Состояние' объекта Car.
public string petName;
public int currSpeed;
// Функциональность Car.
// Использовать синтаксис членов, сжатых до выражений,
// который рассматривался в главе 4.
public void PrintState()
=> Console.WriteLine("{0} is going {1} MPH.", petName, currSpeed);
public void SpeedUp(int delta)
=> currSpeed += delta;
}
Метод PrintState() — простая диагностическая функция, которая выводит текущее состояние объекта Car в окно командной строки. Метод SpeedUp() увеличивает скорость автомобиля, представляемого объектом Car, на величину, которая передается во входном параметре типа int. Обновите операторы верхнего уровня в файле Program.cs, как показано ниже:
Console.WriteLine("***** Fun with Class Types *****n");
// Разместить в памяти и сконфигурировать объект Car.
Car myCar = new Car();
myCar.petName = "Henry";
myCar.currSpeed = 10;
// Увеличить скорость автомобиля в несколько раз и вывести новое состояние.
for (int i = 0; i <= 10; i++)
{
myCar.SpeedUp(5);
myCar.PrintState();
}
Console.ReadLine();
Запустив программу, вы увидите, что переменная Car (myCar) поддерживает свое текущее состояние на протяжении жизни приложения:
***** Fun with Class Types *****
Henry is going 15 MPH.
Henry is going 20 MPH.
Henry is going 25 MPH.
Henry is going 30 MPH.
Henry is going 35 MPH.
Henry is going 40 MPH.
Henry is going 45 MPH.
Henry is going 50 MPH.
Henry is going 55 MPH.
Henry is going 60 MPH.
Henry is going 65 MPH.
Размещение объектов с помощью ключевого слова new
Как было показано в предыдущем примере кода, объекты должны размещаться в памяти с применением ключевого слова new. Если вы не укажете ключевое слово new и попытаетесь использовать переменную класса в последующем операторе кода, то получите ошибку на этапе компиляции. Например, приведенные далее операторы верхнего уровня не скомпилируются:
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();
...
Определение специальных конструкторов
Обычно помимо стандартного конструктора в классах определяются дополнительные конструкторы. Тем самым пользователю объекта предоставляется простой и
- QT 4: программирование GUI на С++ - Жасмин Бланшет - Программирование
- C# для профессионалов. Том II - Симон Робинсон - Программирование
- C# 4.0: полное руководство - Герберт Шилдт - Программирование
- Программирование игр и головоломок - Жак Арсак - Программирование
- Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT. Часть 2 - Александр Фролов - Программирование
- Графические интерфейсы пользователя Java - Тимур Сергеевич Машнин - Программирование
- Гибкое управление проектами и продуктами - Борис Вольфсон - Программирование
- Каждому проекту своя методология - Алистэр Коуберн - Программирование
- От «Энигмы» до ChatGPT - Рустам Агамалиев - Программирование / Экономика
- Как почистить сканы книг и сделать книгу - IvanStorogev? KpNemo - Программирование