русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Расширение без наследования


Дата добавления: 2015-07-09; просмотров: 542; Нарушение авторских прав


 

Предыдущее обсуждение проблемы создания подклассов описывает порядок создания новых классов, наследующих методы других классов. Язык JavaScript настолько гибкий, что создание подклассов и использование механизма насле_ дования – это не единственный способ расширения функциональных возможно_ стей классов. Поскольку функции в JavaScript – это просто значения данных, они могут легко копироваться (или «заимствоваться») из одного класса в дру_ гой. В примере 9.4 демонстрируется функция, которая заимствует все методы одного класса и создает их копии в объекте_прототипе другого класса.

 

Пример 9.4. Заимствование методов одного класса для использования в другом

// Заимствование методов одного класса для использования в другом.

 

// Аргументы должны быть функциями_конструкторами классов.

// Методы встроенных типов, таких как Object, Array, Date и RegExp

 

// не являются перечислимыми и потому не заимствуются этой функцией. function borrowMethods(borrowFrom, addTo) {

 

var from = borrowFrom.prototype; // прототип_источник


 

9.6. Расширение без наследования  
   
var to = addTo.prototype; // прототип_приемник
for(m in from) { // Цикл по всем свойствам прототипа_источника
if (typeof from[m] != "function") continue; // Игнорировать все,
  // что не является функциями
to[m] = from[m]; // Заимствовать метод
}    
}    

 

Многие методы настолько тесно связаны с классом, в котором они определены, что нет смысла пытаться использовать их в другом классе. Однако некоторые методы могут быть достаточно универсальными и пригодяться в любом классе. В примере 9.5 приводятся определения двух классов, ничего особо полезного не делающих, зато реализующих методы, которые могут быть заимствованы дру_ гими классами. Подобные классы, разрабатываемые специально с целью заим_ ствования, называются классами'смесями, или просто смесями.



 

Пример 9.5. Классы'смеси с универсальными методами, предназначенными для заимствования

 

// Сам по себе этот класс не очень хорош. Но он определяет универсальный

 

// метод toString(), который может представлять интерес для других классов. function GenericToString() {}

 

GenericToString.prototype.toString = function( ) { var props = [];

 

for(var name in this) {

 

if (!this.hasOwnProperty(name)) continue; var value = this[name];

 

var s = name + ":" switch(typeof value) { case 'function':

 

s += "function"; break;

 

case 'object':

 

if (value instanceof Array) s += "array" else s += value.toString( );

 

break;

default:

 

s += String(value); break;

 

}

props.push(s);

}

return "{" + props.join(", ") + "}";

}

 

// Следующий класс определяет метод equals(), который сравнивает простые объекты. function GenericEquals() {}

 

GenericEquals.prototype.equals = function(that) { if (this == that) return true;

 

// объекты равны, только если объект this имеет те же свойства,

 

// что и объект that, и не имеет никаких других свойств

// Обратите внимание: нам не требуется глубокое сравнение.

// Значения просто должны быть === друг другу. Из этого следует,


 

188 Глава 9. Классы, конструкторы и прототипы

// если есть свойства, ссылающиеся на другие объекты, они должны ссылаться

 

// на те же самые объекты, а не на объекты, для которых equals() возвращает true var propsInThat = 0;

 

for(var name in that) { propsInThat++;

 

if (this[name] !== that[name]) return false;

}

 

// Теперь необходимо убедиться, что объект this не имеет дополнительных свойств var propsInThis = 0;

 

for(name in this) propsInThis++;

 

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

// следовательно, объекты не равны

if (propsInThis != propsInThat) return false;

 

// Два объекта выглядят равными. return true;

}

 

Вот как выглядит простой класс Rectangle, который заимствует методы toString() и equals(), определенные в классах_смесях:

 

// Простой класс Rectangle function Rectangle(x, y, w, h) {

 

this.x = x; this.y = y; this.width = w; this.height = h;

 

}

Rectangle.prototype.area = function( ) { return this.width * this.height; }

 

// Заимствование некоторых методов

 

borrowMethods(GenericEquals, Rectangle); borrowMethods(GenericToString, Rectangle);

 

Ни один из представленных здесь классов_смесей не имеет собственного конст_ руктора, однако это не значит, что конструкторы нельзя заимствовать. В сле_ дующем фрагменте приводится определение нового класса с именем ColoredRec_ tangle. Он наследует функциональность класса Rectangle и заимствует конструк_ тор и метод из класса_смеси Colored:

// Эта смесь содержит метод, зависящий от конструктора. Оба они,

// и конструктор, и метод должны быть заимствованы.

 

function Colored(c) { this.color = c; } Colored.prototype.getColor = function() { return this.color; }

 

// Определение конструктора нового класса
function ColoredRectangle(x, y, w, h, c) {
this.superclass(x, y, w, h); // Вызов конструктора надкласса
Colored.call(this, c); // и заимствование конструктора Colored
}      

 

// Настройка объекта_прототипа на наследование методов от Rectangle ColoredRectangle.prototype = new Rectangle(); ColoredRectangle.prototype.constructor = ColoredRectangle; ColoredRectangle.prototype.superclass = Rectangle;


 

9.7. Определение типа объекта
   

 

// Заимствовать методы класса Colored в новый класс borrowMethods(Colored, ColoredRectangle);

 

Класс ColoredRectangle расширяет класс Rectangle (и наследует его методы), а так_ же заимствует методы класса Colored. Сам класс Rectangle наследует класс Object и заимствует методы классов GenericEquals и GenericToString. Хотя подобные ана_ логии здесь неуместны, можно воспринимать это как своего рода множественное наследование. Так как класс ColoredRectangle заимствует методы класса Colored, экземпляры класса ColoredRectangle можно одновременно рассматривать как эк_ земпляры класса Colored. Оператор instanceof не сможет сообщить об этом, но в разделе 9.7.3 мы создадим более универсальный метод, который позволит оп_ ределять, наследует или заимствует некоторый объект методы заданного класса.

 



<== предыдущая лекция | следующая лекция ==>
Вызов переопределенных методов | Оператор instanceof и конструктор


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.218 сек.