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

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

Жанры

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

return this;

},

// Остальные методы просто вызывают соответствующие

// методы объекта this.set и ничего более,

remove: function {

this.set.remove.apply(this.set, arguments);

return this;

}.

contains: function(v) {
return this.set.contains(v);},

size: function { return this.set.size; },

foreach: function(f,c) { this.set.foreach(f.c); }

}

)

Одно

из преимуществ применения приема композиции в данном случае заключается в том, что требуется определить только один подкласс
FilteredSe
t. Экземпляры этого класса могут накладывать ограничения на элементы любого другого эк» земпляра множества. Например, вместо класса
NonNullSet
, представленного выше, реализовать подобные ограничения можно было бы так:

var s = new FilteredSet(new Set, function(x) { return x !== null; });

Можно даже наложить еще один фильтр на фильтрованное множество:

var t = new FilteredSet(s, { function(x) { return !(x instanceof Set); });

9.7.4. Иерархии классов и абстрактные классы

В предыдущем разделе было предложено «предпочесть композицию наследованию». Но для иллюстрации этого принципа мы создали подкласс класса

Set
. Сделано это было для того, чтобы получившийся подкласс был
instanceof Set
и наследовал полезные методы класса
Set
, такие как
toString
и
equals.
Это достаточно уважительные причины, но, тем не менее, было бы неплохо иметь возможность использовать прием композиции без необходимости наследовать некоторую определенную реализацию множества, такую как класс
Set
. Аналогичный подход можно было бы использовать и при создании класса
SingletonSet
(пример 9.12) -этот класс был определен как подкласс класса
Set
, чтобы унаследовать вспомогательные методы, но его реализация существенно отличается от реализации суперкласса. Класс
SingletonSet
это не специализированная версия класса
Set
, а совершенно иной тип множеств. В иерархии классов
SingletonSet
должен был бы находиться на одном уровне с классом
Set
, а не быть его потомком.

Решение этой проблемы в классических объектно-ориентированных языках, а также в языке

JavaScript
заключается в том, чтобы отделить интерфейс от реализации. Представьте, что мы определили класс
AbstractSet
, реализующий вспомогательные методы, такие как
toString,
в котором отсутствуют реализации базовых методов, таких как
foreach.
Тогда все наши реализации множеств -
Set, SingletonSet
и
FilteredSet
– могли бы наследовать класс
AbstractSet
. При этом классы
FilteredSet
и
SingletonSet
больше не наследовали бы ненужные им реализации.

Пример 9.16 развивает этот подход еще дальше и определяет иерархию абстрактных классов множеств. Класс

AbstractSet
определяет только один абстрактный метод,
contains.
Любой класс, который претендует на роль множества, должен будет определить хотя бы один этот метод. Далее в примере определяется класс
AbstractEnumerableSet
, наследующий класс
AbstractSet
. Этот класс определяет абстрактные методы
size
and
foreach
и реализует конкретные вспомогательные методы (
toString, toArray, equals
и т.д.).
AbstractEnumerableSet
не определяет методы
add
или
remove
и представляет класс множеств, доступных только для чтения. Класс
SingletonSet
может быть реализован как конкретный подкласс. Наконец, в примере определяется класс
AbstractWritableSet
, наследующий
AbstractEnumerableSet
. Этот последний абстрактный класс определяет абстрактные методы
add
и
remove
и реализует конкретные методы, такие как
union
и
intersection,
использующие их. Класс
AbstractWritableSet
отлично подходит на роль суперкласса для наших классов
Set
и
FilteredSet
. Однако они не были добавлены в пример, а вместо них была включена новая конкретная реализация с именем
ArraySet
.

Пример 9.16 довольно объемен, но он заслуживает детального изучения. Обратите внимание, что для простоты создания подклассов в нем используется функция

Function.prototype.extend.

Пример 9.16. Иерархия абстрактных и конкретных классов множеств

// Вспомогательная функция, которая может использоваться для определения

// любого абстрактного метода

function abstractmethod { throw new Error("абстрактный метод"); }

/*

* Класс AbstractSet определяет единственный абстрактный метод, contains.

*/

function AbstractSet {

throw new Error("Нельзя создать экземпляр абстрактного класса");

}

AbstractSet.prototype.contains = abstractmethod;

/*

* NotSet - конкретный подкласс класса AbstractSet.

* Элементами этого множества являются все значения, которые не являются

* элементами некоторого другого множества. Поскольку это множество

* определяется в терминах другого множества, оно не доступно для записи,

* а так как оно имеет бесконечное число элементов, оно недоступно для перечисления.

* Все, что позволяет этот класс, - это проверить принадлежность к множеству.

* Обратите внимание, что для определения этого подкласса используется метод

* Function.prototype.extendO, объявленный выше.

*/

var NotSet = AbstractSet.extend(

function NotSet(set) { this.set = set; },

{

contains: function(x) { return !this.set.contains(x); },

toString: function(x) { return "~" + this.set.toString; },

equals: function(that) {

return that instanceof NotSet && this.set.equals(that.set);

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

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

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

Я не князь. Книга XIII

Дрейк Сириус
13. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я не князь. Книга XIII

Тьма и Хаос

Владимиров Денис
6. Глэрд
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Тьма и Хаос

Хозяин Теней 6

Петров Максим Николаевич
6. Безбожник
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Хозяин Теней 6

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

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

Пустоши

Сай Ярослав
1. Медорфенов
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Пустоши

Антимаг

Гедеон Александр и Евгения
1. Антимаг
Фантастика:
фэнтези
6.95
рейтинг книги
Антимаг

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

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

Крестоносец

Ланцов Михаил Алексеевич
7. Помещик
Фантастика:
героическая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Крестоносец

Бродяга

Первухин Андрей Евгеньевич
1. Бродяга
Фантастика:
попаданцы
5.40
рейтинг книги
Бродяга

Чевенгур

Платонов Андрей Платонович
Проза:
советская классическая проза
6.75
рейтинг книги
Чевенгур

Я до сих пор не царь. Книга XXVII

Дрейк Сириус
27. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я до сих пор не царь. Книга XXVII

Кукла

Прус Болеслав
Проза:
классическая проза
8.87
рейтинг книги
Кукла

Кодекс Охотника XXXI

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