передается объект формы, которую следует отобразить. Это классика

жанра — так мы будем поступать каждый раз, когда захотим увидеть на

экране ту или иную форму.

После того как пройдет эйфория по поводу созданного окна, станет со-

вершенно очевидно, что в окнах подобного рода пользы нет никакой.

Нам нужны добротные и функциональные оконные формы. Чтобы на-

учиться их создавать, предстоит серьезно расширить наши горизонты

в области основ языка 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();

}

}

Идея такая: класс А содержит текстовое поле и метод для отображения зна-

чения этого поля. На основе класса А путем наследования создается класс

В, который получает поле и метод класса А и, кроме них, добавляет в свой

арсенал еще одно текстовое поле и еще один метод, который отображает

значение обоих текстовых полей. На основе класса В, опять же путем на-

следования, создается класс С. Класс С получает в наследство два тексто-

вых поля и два метода из класса В, и в нем описано еще одно текстовое поле

и метод, который позволяет отобразить в консоли значения всех трех полей

Перейти на страницу:

Похожие книги