особенности которого позволяют создавать подобные вспомогательные конструкторы (раздел 8.7.4).
9.7. Подклассы
В объектно-ориентированном программировании класс В может расширять, или наследовать, другой класс А. Класс А в этом случае называется суперклассом, а класс В - подклассом. Экземпляры класса В наследуют все методы экземпляров
класса А. Класс В может определять собственные методы экземпляров, некоторые из которых могут переопределять методы класса А с теми же именами. Если метод класса В переопределяет метод класса А, переопределяющий метод класса В может вызывать переопределенный метод класса А: этот прием называется вызовом метода базового класса. Аналогично конструктор В подкласса может вызывать конструктор А суперкласса. Это называется вызовом конструктора базового класса. Подклассы сами могут наследоваться другими подклассами и, работая над созданием иерархии классов, иногда бывает полезно определять абстрактные классы. Абстрактный класс - это класс, в котором объявляется один или более методов без реализации. Реализация таких абстрактных методов возлагается на конкретные подклассы абстрактного класса.
Ключом к созданию подклассов в языке JavaScript является корректная инициализация объекта-прототипа. Если класс В расширяет класс А, то объект В.prototype должен наследовать
A.prototype
. В этом случае экземпляры класса В будут наследовать свойства от объекта
В.prototype
, который в свою очередь наследует свойства от
A.prototype
. В этом разделе демонстрируются все представленные выше термины, связанные с подклассами, а также рассматривается прием, альтернативный наследованию, который называется композицией.
Используя в качестве основы класс
Set
из примера 9.6, этот раздел продемонстрирует, как определять подклассы, как вызывать конструкторы базовых классов и переопределенные методы, как вместо наследования использовать прием композиции и, наконец, как отделять интерфейсы от реализации с помощью абстрактных классов. Этот раздел завершает расширенный пример, в котором определяется иерархия классов
Set
. Следует отметить, что первые примеры в этом разделе служат цели продемонстрировать основные приемы использования механизма наследования, и некоторые из них имеют существенные недостатки, которые будут обсуждаться далее в этом же разделе.
9.7.1. Определение подкласса
В языке JavaScript объекты наследуют свойства (обычно методы) от объекта-прототипа своего класса. Если объект
O
является экземпляром класса
В
, а класс
В
является подклассом класса
А
, то объект
O
также наследует свойства класса
А
. Добиться этого можно за счет наследования объектом-прототипом класса
Пример 9.12 демонстрирует, как определить подкласс «вручную», без использования функции def ineSubclass. В этом примере определяется подкласс SingletonSet класса Set. Класс SingletonSet представляет специализированное множество, доступное только для чтения и состоящее из единственного постоянно элемента.
Пример 9.12. SingletonSet: простой подкласс множеств
// Функция-конструктор
function SingletonSet(member) {
this.member = member; // Сохранить единственный элемент множества
}
// Создает объект-прототип, наследующий объект-прототип класса Set.
SingletonSet.prototype = inherit(Set.prototype);
// Далее добавляются свойства в прототип.
// Эти свойства переопределяют одноименные свойства объекта
Set.prototype. extend(SingletonSet.prototype, {
// Установить свойство constructor
constructor: SingletonSet,
// Данное множество доступно только для чтения: методы add и remove