Сборка от 17 марта 2017 г



Download 9,9 Mb.
bet228/349
Sana26.04.2022
Hajmi9,9 Mb.
#582433
TuriУчебник
1   ...   224   225   226   227   228   229   230   231   ...   349
Bog'liq
ilja kantor sovremennyj uchebnik-1chast PdfToWord

Переопределение методов


Итак, мы получили класс CoffeeMachine , который наследует от Machine .


Аналогичным образом мы можем унаследовать от Machine холодильник Fridge , микроволновку MicroOven и другие классы, которые разделяют общий «машинный» функционал, то есть имеют мощность и их можно включать/выключать.


Для этого достаточно вызвать Machine в текущем контексте, а затем добавить свои методы.

// Fridge может добавить и свои аргументы,


// которые в Machine не будут использованы function Fridge(power, temperature) {
Machine.apply(this, arguments);

// ...
}


Бывает так, что реализация конкретного метода машины в наследнике имеет свои особенности. Можно, конечно, объявить в CoffeeMachine свой enable :


function CoffeeMachine(power, capacity) { Machine.apply(this, arguments);


// переопределить this.enable this.enable = function() {


/* enable для кофеварки */
};
}

…Однако, как правило, мы хотим не заменить, а расширить метод родителя, добавить к нему что‑то. Например, сделать так, чтобы при включении кофеварка тут же запускалась.


Для этого метод родителя предварительно копируют в переменную, и затем вызывают внутри нового enable – там, где считают нужным:


function CoffeeMachine(power) { Machine.apply(this, arguments);
var parentEnable = this.enable; // (1) this.enable = function() { // (2)
parentEnable.call(this); // (3)
this.run(); // (4)
}

...
}




Общая схема переопределения метода (по строкам выделенного фрагмента кода):




  1. Копируем доставшийся от родителя метод this.enable в переменную, например parentEnable .

  2. Заменяем this.enable на свою функцию…

  3. …Которая по‑прежнему реализует старый функционал через вызов parentEnable .

  4. …И в дополнение к нему делает что‑то своё, например запускает приготовление кофе.

Обратим внимание на строку (3) .

В ней родительский метод вызывается так: parentEnable.call(this) . Если бы вызов был таким: parentEnable() , то ему бы не передался текущий


this и возникла бы ошибка.

Технически, можно сделать возможность вызывать его и как parentEnable() , но тогда надо гарантировать, что контекст будет правильным, например привязать его при помощи bind или при объявлении, в родителе, вообще не использовать this , а получать контекст через замыкание, вот так:


function Machine(power) { this._enabled = false;


var self = this; this.enable = function() {
// используем внешнюю переменную вместо this
self._enabled = true;
};

this.disable = function() { self._enabled = false;


};

}


function CoffeeMachine(power) { Machine.apply(this, arguments);
var waterAmount = 0; this.setWaterAmount = function(amount) {
waterAmount = amount;
};
var parentEnable = this.enable; this.enable = function() {
parentEnable(); // теперь можно вызывать как угодно, this не важен this.run();
}

function onReady() { alert( 'Кофе готово!' );


}

this.run = function() { setTimeout(onReady, 1000);


};

}


var coffeeMachine = new CoffeeMachine(10000); coffeeMachine.setWaterAmount(50); coffeeMachine.enable();

В коде выше родительский метод parentEnable = this.enable успешно продолжает работать даже при вызове без контекста. А всё потому, что использует self внутри.




Итого


Организация наследования, которая описана в этой главе, называется «функциональным паттерном наследования». Её общая схема (кратко):



  1. Объявляется конструктор родителя Machine . В нём могут быть приватные (private), публичные (public) и защищённые (protected) свойства:

function Machine(params) {


// локальные переменные и функции доступны только внутри Machine var privateProperty;

// публичные доступны снаружи this.publicProperty = ...;


// защищённые доступны внутри Machine и для потомков


// мы договариваемся не трогать их снаружи this._protectedProperty = ...
}

var machine = new Machine(...) machine.public();





  1. Для наследования конструктор потомка вызывает родителя в своём контексте через apply . После чего может добавить свои переменные и методы:

function CoffeeMachine(params) {


// универсальный вызов с передачей любых аргументов
Machine.apply(this, arguments);

this.coffeePublicProperty = ...


}

var coffeeMachine = new CoffeeMachine(...); coffeeMachine.publicProperty(); coffeeMachine.coffeePublicProperty();





  1. В CoffeeMachine свойства, полученные от родителя, можно перезаписать своими. Но обычно требуется не заменить, а расширить метод родителя. Для этого он предварительно копируется в переменную:

function CoffeeMachine(params) { Machine.apply(this, arguments);
var parentProtected = this._protectedProperty; this._protectedProperty = function(args) {
parentProtected.apply(this, args); // (*)
// ...
};
}

Строку (*) можно упростить до parentProtected(args) , если метод родителя не использует this , а, например, привязан к var self = this :


function Machine(params) { var self = this;


this._protected = function() { self.property = "value";


};
}

Надо сказать, что способ наследования, описанный в этой главе, используется нечасто.


В следующих главах мы будем изучать прототипный подход, который обладает рядом преимуществ.


Но знать и понимать его необходимо, поскольку во многих существующих библиотеках классы написаны в функциональном стиле, и расширять/ наследовать от них можно только так.


Задачи






Download 9,9 Mb.

Do'stlaringiz bilan baham:
1   ...   224   225   226   227   228   229   230   231   ...   349




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish