передается объект формы, которую следует отобразить. Это классика
жанра — так мы будем поступать каждый раз, когда захотим увидеть на
экране ту или иную форму.
После того как пройдет эйфория по поводу созданного окна, станет со-
вершенно очевидно, что в окнах подобного рода пользы нет никакой.
Нам нужны добротные и функциональные оконные формы. Чтобы на-
учиться их создавать, предстоит серьезно расширить наши горизонты
в области основ языка C#. Поэтому с высот базовых принципов ООП
опускаемся к более насущным задачам. О них пойдет речь в следующей
главе.
Объектные переменные и наследование 81
ПРИМЕЧАНИЕ Выше мы сокрушались по поводу того, что в окне нет управляющих
элементов — ни тебе кнопок, ни списков, вообще ничего. Так вот, добавить все эти детали в окно достаточно просто. Намного сложнее
научить элементы управления правильному поведению. Вообще, са-
мый сложный этап в программировании приложений с графическим
интерфейсом связан с обработкой событий. Именно благодаря обра-
ботке событий компоненты оживают, становятся функциональными.
По сравнению с этим весь этот оконный декор является сплошной
забавой.
Вместе с тем закрыты еще не все вопросы, касающиеся классов и объектов.
Частично мы их будем закрывать по ходу книги, а несколько важных во-
просов рассмотрим прямо сейчас.
Объектные переменные
и наследование
Я унаследовал всех врагов своего отца
и лишь половину его друзей.
Мы уже знаем, что объектная переменная — это переменная, которая ссы-
лается на объект. Значением объектной переменной является некий адрес
(который сам по себе нам ни о чем не говорит), и, когда мы обращаемся
к объектной переменной, она автоматически передает наше обращение объ-
екту, адрес которого она хранит. При объявлении объектной переменной
мы в качестве ее типа указывали имя класса, на объекты которого в прин-
ципе может ссылаться переменная. Все вроде бы понятно. Возникает во-
прос: при чем тут наследование? Ответ такой: переменная базового класса
может ссылаться на объект производного класса. Другими словами, если
класс B наследует класс A, то мы можем объявить объектную переменную
класса A, а в качестве значения присвоить ей ссылку на объект класса B.
Правда, здесь есть одно серьезное ограничение: через объектную перемен-
ную базового класса в объекте производного класса можно ссылаться толь-
ко на те члены, которые описаны в базовом классе. Так, если переменная
класса A ссылается на объект класса B, то доступ будет только к тем членам
класса B, которые унаследованы им из класса A.
В листинге 2.7 представлен пример, в котором есть и объектные перемен-
ные, и производные классы.
82
Глава 2. Классы и объекты
Листинг 2.7. Объектные переменные и наследование
using System;
// Базовый класс A:
class A{
// Открытое текстовое поле:
public string nameA;
// Открытый метод для отображения значения поля:
public void showA(){
Console.WriteLine("Метод класса А: "+nameA);
}
}
// Производный класс B от базового класса A:
class B:A{
// Еще одно открытое текстовое поле:
public string nameB;
// Открытый метод для отображения
// значения двух полей:
public void showB(){
Console.WriteLine("Метод класса B: "+nameA+" и "+nameB);
}
}
// Производный класс C от базового класса B:
class C:B{
// Новое открытое текстовое поле:
public string nameC;
// Открытый метод для отображения
// значения трех полей:
public void showC(){
Console.WriteLine("Метод класса C: "+nameA+",
"+nameB+" и "+nameC);
}
}
// Класс с главным методом программы:
class ABCDemo{
// Главный метод программы:
public static void Main(){
// Объектная переменная класса A:
A objA;
// Объектная переменная класса B:
B objB;
// Объектная переменная и объект класса C:
C objC=new C();
// Объектной переменной класса A
// в качестве значения
// присваивается ссылка на объект класса C:
objA=objC;
Объектные переменные и наследование 83
// Объектной переменной класса B
// в качестве значения
// присваивается ссылка на объект класса C:
objB=objC;
// Доступ к объекту класса C
// через переменную класса B.
// Поле nameC и метод showC() недоступны:
objB.nameA="красный";
objB.nameB="желтый";
objB.showA();
objB.showB();
// Доступ к объекту класса C через
// переменную класса C.
// Доступно все:
objC.nameC="зеленый";
objC.showC();
// Доступ к объекту класса C через
// переменную класса A.
// Доступны поле nameA и метод showA():
objA.nameA="белый";
objA.showA();
// Ожидание нажатия клавиши (любой):
Console.ReadKey();
}
}
Идея такая: класс А содержит текстовое поле и метод для отображения зна-
чения этого поля. На основе класса А путем наследования создается класс
В, который получает поле и метод класса А и, кроме них, добавляет в свой
арсенал еще одно текстовое поле и еще один метод, который отображает
значение обоих текстовых полей. На основе класса В, опять же путем на-
следования, создается класс С. Класс С получает в наследство два тексто-
вых поля и два метода из класса В, и в нем описано еще одно текстовое поле
и метод, который позволяет отобразить в консоли значения всех трех полей