зовым классом Box. А разбираться есть с чем. Так, у класса Box имеется за-

крытое поле size (которое определяет длину ребра коробки), два варианта

конструктора (без аргументов и с одним аргументом), а также несколько

методов. Для присваивания значения полю size предназначен метод set(), который не возвращает результат. Единственный аргумент определяет

значение, присваиваемое полю size. Метод объявлен с атрибутом private, что означает исключительную закрытость метода — он не только недосту-

пен вне класса, но и не будет напрямую доступен и в производном классе, как и поле size. Мы используем этот метод в конструкторах класса для

того, чтобы присвоить полю size значение. Метод show() предназначен

для отображения значения поля size (с пояснениями). Метод защищен-

ный, поэтому он недоступен за пределами базового класса, но наследуется

в производном классе (но он недоступен вне производного класса).

Конструктор класса с одним аргументом достаточно прост — методом set() полю size присваивается значение. Поэтому код этой версии конструкто-

ра где-то даже банален. А вот по-настоящему интригующим является код

конструктора без аргументов: public Box():this(10){}. Интерес читателя, возможно, вызовет инструкция this(10), указанная через двоеточие после

имени конструктора. Это команда для вызова конструктора с аргументом

10. Пустые фигурные скобки означают, что, кроме этого, больше никаких

действий выполнять не нужно (хотя при желании туда можно было бы что-

то вписать). Таким образом, вызов конструктора без аргументов означает

вызов конструктора с одним аргументом, равным 10. Все просто.

При объявлении производного класса ColoredBox после имени класса че-

рез двоеточие указываем имя базового класса Box. Это простое на первый

взгляд обстоятельство имеет серьезные последствия: класс ColoredBox по-

лучает от класса Box в полное и безвозмездное распоряжение все незакры-

тые (открытые и защищенные) члены, да и закрытые члены базового клас-

са не так недоступны, как может показаться.

При создании объекта производного класса сначала вызывается кон-

структор базового класса. Таковы суровые законы наследования. Аргу-

менты конструктора базового класса указываются в круглых скобках

после  ключевого  слова  base.  Непосредственно  программный  код

конструктора производного класса указывается, как обычно, в фи-

гурных скобках. Но все эти действия выполняются после того, как

будет выполнен соответствующий конструктор базового класса.

Кроме богатого и щедрого наследства, класс ColoredBox имеет и собственные

достижения в виде закрытого текстового поля color, защищенного метода

Наследование и уровни доступа           77

showAll() и трех вариантов конструктора (без аргументов, с одним аргу-

ментом и с двумя аргументами). С конструкторов и начнем. Все они имеют

некоторую особенность в виде инструкции base() (с аргументами или без), которая через двоеточие указывается после имени конструктора. Такая ин-

струкция есть не что иное, как вызов конструктора базового класса.

Другими словами, за ту часть объекта, что описана в базовом классе, отве-

чает конструктор базового класса. За поля и методы, описанные непосред-

ственно в производном классе, отвечает конструктор производного клас-

са. Ключевое слово base (с аргументами или без) можно и не указывать

в описании конструктора производного класса. В этом случае все равно

будет вызываться конструктор базового класса — это будет конструктор

по умолчанию (конструктор без аргументов).

В теле конструктора производного класса полю color присваивается зна-

чение, после чего методом showAll() информация о значениях полей size и color выводится в консоль. В методе showAll(), кроме прочего, вызыва-

ется унаследованный из базового класса метод show().

ПРИМЕЧАНИЕ Формально поля size у класса ColoredBox как бы и нет, поскольку

это поле объявлено в базовом классе Box как закрытое. Во всяком

случае, в программном коде класса ColoredBox на поле size ссылаться

бесполезно — классу об этом поле ничего неизвестно. Тем не менее

технически это поле существует, и такой метод, как show(), насле-

дуемый в производном классе, преспокойно отображается к этому

полю. Значение этому несуществующему полю присваивается, когда

в  конструкторе  производного  класса  вызывается  конструктор  ба-

зового класса, в котором, в свою очередь, вызывается метод set(), о котором производный класс тоже ничего не знает.

В главном методе программы мы, вызывая разные конструкторы, создаем

три объекта производного класса. При этом в консоль выводятся сообще-

ния. Результат работы программы показан на рис. 2.3.

Рис. 2.3.  Результат работы программы с базовым и производным классами

78

Глава 2. Классы и объекты

ПРИМЕЧАНИЕ Особо любопытным интересно будет узнать, что, помимо атрибутов

public, private и protected, определяющих уровень доступа членов

класса, в C# есть еще и атрибут internal. Член класса, описанный с этим

атрибутом, доступен в пределах компоновочного файла. Такого типа

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

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