зовым классом 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. Член класса, описанный с этим
атрибутом, доступен в пределах компоновочного файла. Такого типа