Чтение онлайн

на главную - закладки

Жанры

JavaScript. Подробное руководство, 6-е издание
Шрифт:

Один из способов реализовать такую возможность заключается в создании перегруженных версий конструктора и выполнении в них различных способов инициализации в зависимости от передаваемых аргументов. Ниже приводится пример перегруженной версии конструктора

Set
:

function Set {

this.values = {}; // Свойство для хранения множества

this.n =0; // Количество значений в множестве

// Если конструктору передается единственный объект, подобный массиву,

// он добавляет элементы массива в множество.

// В противном случае в множество добавляются все аргументы

if (arguments.length == 1 && isArraylike(arguments[0]))

this.add.apply(this, arguments[0]);

else

if (arguments.length > 0)

this.add.apply(this, arguments);

}

Такое определение конструктора

Set
позволяет явно перечислять элементы множества в вызове конструктора или передавать ему массив элементов множества. К сожалению, этот конструктор имеет одну неоднозначность: его нельзя использовать для создания множества, содержащего единственный элемент-массив. (Для этого потребуется создать пустое множество, а затем явно вызвать метод
add
.)

В случае с комплексными числами реализовать перегруженную версию конструктора, которая инициализирует объект полярными координатами, вообще невозможно. Оба представления комплексных чисел состоят из двух вещественных чисел. Если не добавить в конструктор третий аргумент, он не сможет по своим аргументам определить, какое представление следует использовать. Однако вместо этого можно написать фабричный метод - метод класса, возвращающий экземпляр класса. Ниже приводится фабричный метод, возвращающий объект

Complex
, инициализированный полярными координатами:

Complex.polar = function(r, theta) {

return new Complex(r*Math.cos(theta), r*Math.sin(theta));

};

А так можно реализовать фабричный метод для инициализации объекта

Set
массивом:

Set.fromArray = function(a) {

s = new Set; // Создать пустое множество

s.add.apply(s, a); // Передать элементы массива методу add

return s; // Вернуть новое множество

};

Привлекательность фабричных методов заключается в том, что им можно дать любые имена, а методы с разными именами могут выполнять разные виды инициализации. Поскольку конструкторы играют роль имен классов, обычно в классах определяется единственный конструктор. Однако это не является непреложным правилом. В языке JavaScript допускается определять несколько функций-конструкторов, использующих общий объект-прототип, и в этом случае объекты, созданные разными конструкторами одного класса, будут иметь один и тот же тип. Данный прием не рекомендуется к использованию, тем не менее ниже приводится вспомогательный конструктор такого рода:

// Вспомогательный конструктор для класса Set.

function SetFromArray(a) {

// Инициализировать новый объект вызовом конструктора Set как функции,

// передав ей элементы массива в виде отдельных аргументов.

Set.apply(this, а);

}

// Установить прототип, чтобы функция SetFromArray создавала экземпляры Set

SetFromArray.prototype = Set.prototype;

var s = new SetFromArray([1,2,3]);

s instanceof Set // => true

В ECMAScript 5 функции имеют метод

bind,
особенности которого позволяют создавать подобные вспомогательные конструкторы (раздел 8.7.4).

9.7. Подклассы

В объектно-ориентированном программировании класс В может расширять, или наследовать, другой класс А. Класс А в этом случае называется суперклассом, а класс В - подклассом. Экземпляры класса В наследуют все методы экземпляров класса А. Класс В может определять собственные методы экземпляров, некоторые из которых могут переопределять методы класса А с теми же именами. Если метод класса В переопределяет метод класса А, переопределяющий метод класса В может вызывать переопределенный метод класса А: этот прием называется вызовом метода базового класса. Аналогично конструктор В подкласса может вызывать конструктор А суперкласса. Это называется вызовом конструктора базового класса. Подклассы сами могут наследоваться другими подклассами и, работая над созданием иерархии классов, иногда бывает полезно определять абстрактные классы. Абстрактный класс - это класс, в котором объявляется один или более методов без реализации. Реализация таких абстрактных методов возлагается на конкретные подклассы абстрактного класса.

Ключом к созданию подклассов в языке JavaScript является корректная инициализация объекта-прототипа. Если класс В расширяет класс А, то объект В.prototype должен наследовать

A.prototype
. В этом случае экземпляры класса В будут наследовать свойства от объекта
В.prototype
, который в свою очередь наследует свойства от
A.prototype
. В этом разделе демонстрируются все представленные выше термины, связанные с подклассами, а также рассматривается прием, альтернативный наследованию, который называется композицией.

Используя в качестве основы класс

Set
из примера 9.6, этот раздел продемонстрирует, как определять подклассы, как вызывать конструкторы базовых классов и переопределенные методы, как вместо наследования использовать прием композиции и, наконец, как отделять интерфейсы от реализации с помощью абстрактных классов. Этот раздел завершает расширенный пример, в котором определяется иерархия классов
Set
. Следует отметить, что первые примеры в этом разделе служат цели продемонстрировать основные приемы использования механизма наследования, и некоторые из них имеют существенные недостатки, которые будут обсуждаться далее в этом же разделе.

Поделиться:
Популярные книги

Кодекс Охотника. Книга III

Винокуров Юрий
3. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
7.00
рейтинг книги
Кодекс Охотника. Книга III

Геном хищника. Книга пятая

Гарцевич Евгений Александрович
5. Я - Легенда!
Фантастика:
рпг
фэнтези
попаданцы
6.00
рейтинг книги
Геном хищника. Книга пятая

Неучтенный элемент. Том 3

NikL
3. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 3

Монстр из прошлого тысячелетия

Еслер Андрей
5. Соприкосновение миров
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Монстр из прошлого тысячелетия

Кодекс Охотника. Книга XVII

Винокуров Юрий
17. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XVII

Чайлдфри

Тоцка Тала
Любовные романы:
современные любовные романы
6.51
рейтинг книги
Чайлдфри

Запечатанный во тьме. Том 2

NikL
2. Хроники Арнея
Фантастика:
уся
эпическая фантастика
фэнтези
5.00
рейтинг книги
Запечатанный во тьме. Том 2

На границе империй. Том 10. Часть 7

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 7

Журнал «Если», 2002 № 08

Андерсон Кевин Джей
114. Журнал Если
Фантастика:
научная фантастика
5.00
рейтинг книги
Журнал «Если», 2002 № 08

Ким

Киплинг Редьярд Джозеф
Приключения:
исторические приключения
7.62
рейтинг книги
Ким

Криптозой

Головачев Василий Васильевич
Фантастика:
научная фантастика
6.25
рейтинг книги
Криптозой

Оживший камень

Кас Маркус
1. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Оживший камень

Ваше Сиятельство 7

Моури Эрли
7. Ваше Сиятельство
Фантастика:
боевая фантастика
аниме
5.00
рейтинг книги
Ваше Сиятельство 7

Уникум

Поселягин Владимир Геннадьевич
1. Уникум
Фантастика:
альтернативная история
4.60
рейтинг книги
Уникум