virtual public void show(){
Console.WriteLine("Класс А: "+name);
}
}
// Производный класс от класса A:
class B:A{
// Конструктор класса:
public B(string txt):base(txt){}
// Переопределение метода в производном классе:
override public void show(){
Console.WriteLine("Класс B: "+name);
}
}
// Производный класс от класса B:
class C:B{
// Конструктор класса:
public C(string txt):base(txt){}
}
// Производный класс от класса C:
class D:C{
// Конструктор класса:
public D(string txt):base(txt){}
// Переопределение метода в производном классе:
override public void show(){
Console.WriteLine("Класс D: "+name);
}
}
// Класс с главным методом программы:
class VirtualDemo{
// Главный метод программы:
public static void Main(){
// Объектная переменная класса A:
A obj;
// Переменная класса A ссылается на
// объект класса A:
obj=new A("поле класса А");
// Вызов метода show() объекта класса A
// через объектную переменную класса A:
obj.show();
// Переменная класса A ссылается на
// объект класса B:
obj=new B("поле класса B");
92
Глава 2. Классы и объекты
Листинг 2.9 (продолжение)
// Вызов метода show() объекта класса B
// через объектную переменную класса A:
obj.show();
// Переменная класса A ссылается на
// объект класса C:
obj=new C("поле класса C");
// Вызов метода show() объекта класса C
// через объектную переменную класса A:
obj.show();
// Переменная класса A ссылается на
// объект класса D:
obj=new D("поле класса D");
// Вызов метода show() объекта класса D
// через объектную переменную класса A:
obj.show();
// Ожидание нажатия какой-нибудь клавиши:
Console.ReadKey();
}
}
В программе описывается четыре класса с именами A, B, C и D. Они по це-
почке наследуют друг друга: класс B создается на основе класса A, класс C
создается на основе класса B, а класс D создается на основе класса C. В клас-
се A описано открытое текстовое поле name, которое наследуется всеми
классами в цепочке наследования, а также виртуальный метод show(), ко-
торый переопределяется в производных классах. Точнее, он переопреде-
ляется в классе B, в классе C наследуется из класса B без переопределения, а в классе D снова переопределяется. Там, где метод переопределяется, он
описан так, что кроме значения поля name выводит сообщение о том, какого
класса этот метод. Также у каждого из классов есть конструктор с одним
аргументом, который присваивается в качестве значения полю name.
В главном методе программы создается объектная переменная obj класса A, после чего она последовательно «получает в подарок» ссылки на объекты
разных классов. И каждый раз из объектной переменной obj вызывается
метод show(). На рис. 2.7 представлен результат выполнения программы.
Рис. 2.7. Переопределение виртуальных методов: результат выполнения программы
Статические члены класса 93
Несмотря на то, что для объектов каждого из четырех классов метод show() вызывается через объектную переменную класса A (который находится
в вершине нашей импровизированной иерархии наследования), для каж-
дого из объектов вызывается правильный метод — тот метод, который опи-
сан в классе объекта, а не в классе объектной переменной. Таким образом, для виртуальных переопределенных методов вопрос о том, какую версию
метода вызывать (старую, унаследованную из базового класса, или новую, переопределенную в производном классе) решается на основе типа объ-
екта, на который ссылается объектная переменная, а не на основе типа объ-
ектной переменной.
Независимо от того, переопределяется или замещается метод, его
старая версия из базового класса доступна через base-ссылку.
Из этого примера также видно, что свойство виртуальности наследуется.
Так, в классе C мы явно не переопределяли метод show(). Поэтому у клас-
са C версия метода show() такая же, как и у класса B. А вот в классе D мы
метод снова переопределили так, как если бы он был объявлен в классе C
как виртуальный. Другими словами, виртуальность метода декларируется
единожды.
Статические члены класса
Не копируйте человека, если вы
неспособны ему подражать.
У классов могут быть
является ключевое слово static. Такой атрибут мы встречаем постоянно —
каждый раз главный метод программы описывается с таким атрибутом.
Настало время разобраться в том, что же такое статические члены клас-
са, и в чем их особенности. Здесь мы остановимся только на самых общих
и наиболее важных с прикладной точки зрения моментах, связанных с ис-
пользованием статических членов.
Статический член от обычного, нестатического члена класса, отличается
в первую очередь тем, что он один для всех экземпляров класса. Более того, статический член класса можно использовать даже в том случае, если ни
один объект в классе не создан. Как мы уже знаем, описание статического
члена класса выполняется с ключевым словом static. Вызов статического
94
Глава 2. Классы и объекты
члена класса выполняется в формате имя_класса.статически_член, то есть