JavaScript. Подробное руководство, 6-е издание, стр. 128
Решение этой проблемы в классических объектно-ориентированных языках, а также в языке
<b>JavaScript</b><b>AbstractSet</b><b>toString(),</b><b>foreach().</b><b>Set, SingletonSet</b><b>FilteredSet</b><b>AbstractSet</b><b>FilteredSet</b><b>SingletonSet</b>Пример 9.16 развивает этот подход еще дальше и определяет иерархию абстрактных классов множеств. Класс
<b>AbstractSet</b><b>contains().</b><b>AbstractEnumerableSet</b><b>AbstractSet</b><b>size()</b><b>foreach()</b><b>toString(), toArray(), equals()</b><b>AbstractEnumerableSet</b><b>add()</b><b>remove()</b><b>SingletonSet </b><b>AbstractWritableSet</b><b>AbstractEnumerableSet</b><b>add()</b><b>remove()</b><b>union()</b><b>intersection(),</b><b>AbstractWritableSet</b><b>Set</b><b>FilteredSet</b><b>ArraySet</b>Пример 9.16 довольно объемен, но он заслуживает детального изучения. Обратите внимание, что для простоты создания подклассов в нем используется функция
<b>Function.prototype.extend().</b>Пример 9.16. Иерархия абстрактных и конкретных классов множеств
<b>// Вспомогательная функция, которая может использоваться для определения</b><b>// любого абстрактного метода</b><b>function abstractmethod() { throw new Error("абстрактный метод"); }</b><b>/*</b><b> * Класс AbstractSet определяет единственный абстрактный метод, contains().</b><b>*/</b><b>function AbstractSet() {</b><b> throw new Error("Нельзя создать экземпляр абстрактного класса");</b><b>}</b><b>AbstractSet.prototype.contains = abstractmethod;</b><b>/*</b><b> * NotSet - конкретный подкласс класса AbstractSet.</b><b> * Элементами этого множества являются все значения, которые не являются</b><b> * элементами некоторого другого множества. Поскольку это множество</b><b> * определяется в терминах другого множества, оно не доступно для записи,</b><b> * а так как оно имеет бесконечное число элементов, оно недоступно для перечисления.</b><b> * Все, что позволяет этот класс, - это проверить принадлежность к множеству.</b><b> * Обратите внимание, что для определения этого подкласса используется метод</b><b> * Function.prototype.extendO, объявленный выше.</b><b>*/</b><b>var NotSet = AbstractSet.extend(</b><b> function NotSet(set) { this.set = set; },</b><b> {</b><b> contains: function(x) { return !this.set.contains(x); },</b><b> toString: function(x) { return "~" + this.set.toString(); },</b><b> equals: function(that) {</b><b> return that instanceof NotSet && this.set.equals(that.set);</b><b> }</b><b> }</b><b>);</b><b>/*</b><b> * AbstractEnumerableSet - абстрактный подкласс класса AbstractSet.</b><b> * Определяет абстрактные методы size() и foreach() и реализует конкретные</b><b> * методы isEmptyO. toArrayO, to[Locale]String() и equals().</b><b> * Подклассы, реализующие методы contains(), size() и foreach(),</b><b> * получают эти пять конкретных методов даром.</b>