Основное различие между Extends и Implements состоит в том, что Implement изменяет прототип класса, а Extend создает копию. Это означает, что если вы реализуете изменение в классе, все экземпляры этого класса мгновенно наследуют это изменение, а если вы используете Extend, то все существующие экземпляры останутся прежними.
это цитата из моторики, зацените. http://mootorial.com/wiki/mootorial/02-class/#implement-vs.-extend
что касается тестирования - я очень рекомендую вам создать несколько примеров с классами ниндзя и поместить их в http://www.jsfiddle.net - затем попросить аналитический совет или список рассылки mootools в Google или IRC ( irc.freenode.net # mootools), SO, похоже, не получает много хитов от основной команды mootools. В идеале вы хотите поговорить с кем-то вроде Аарона Ньютона, Ариана, cpojer или rpflo:)
обновление: Я даже писал об этом в блоге, но был неправ. Просто есть разница в порядке, в котором вводятся такие мутаторы, как Extends
и Implements
. Вы можете реализовать и расширить, но вам нужно сначала объявить Extends, чтобы он работал.
Подробнее здесь: http://fragged.org/mootools-pattern-fun-class-implements-extends-at-the-same-time_1359.html
update Оказывается, в некоторых случаях это полезно. Вот проблема:
var ninja = new Class({
kill: function() {
alert("kill!");
}
});
var human = new Class({
initialize: function(){
alert("i r human!");
}
});
var badass = new Class({
Implements: [ninja],
Extends: human,
initialize: function() {
alert("i r badass and.. ");
this.parent();
this.kill();
}
});
new badass(); // i r badass, i r human, this.kill is not a function exception.
... просто не работает. Вам нужен класс человек для реализации ниндзя вместо этого и класс задира , чтобы просто расширить человека . Помимо побочного эффекта от людей, получающих новый метод убийства (о которых они могут знать, а могут и не знать), это будет означать, что задира сможет использовать .kill, а также будет призывать своего непосредственного родителя - человека.
Почему бы не переписать вещи так, как вы хотите, и без осложнений? Потому что вы можете расширять собственный класс, такой как Request.JSONP, а затем решите смешать новый класс хранения с вашим расширенным. Реальная история ... В любом случае, вы не можете позволить себе роскошь рефакторинга определенных классов, доступных вам.
Интересный шаблон для преодоления этого (рассмотрите человеческий класс your request.jsonp, определенный в другом месте) - если вы просто хотите добавить больше методов и свойств в расширяемый класс, но не планируете повторно использовать класс mixin ( ниндзя):
human.implement(new new Class({
kill: function() {
alert("kill!");
}
}));
var badass = new Class({
Extends: human,
initialize: function() {
alert("i r badass and.. ");
this.parent();
this.kill();
}
});
new badass(); // // i r badass, i r human, kill!
Возможно, вы могли бы просто сделать human.implement({ method: function });
, но класс может быть намного больше.
Если вы хотите сохранить сохраненную ссылку на свой класс ниндзя для других целей, вышеприведенное будет таким же (если вы планируете повторно использовать свой миксин):
var ninja new Class({
kill: function() {
alert("kill!");
}
});
human.implement(new ninja);
// this is what differs from say - instantiation + shared inherited properties.
// also, a constructor will work.
// the alternative would just do:
// human.prototype.kill = function() { alert("kill"); }
var badass = new Class({
Extends: human,
initialize: function() {
alert("i r badass and.. ");
this.parent();
this.kill();
}
});
new badass(); // // i r badass, i r human, kill!
Надеюсь, это кому-нибудь поможет. Вот практический пример, где я расширяю Request.JSONP дополнительным классом хранилища в качестве миксина: http://jsfiddle.net/dimitar/YacZe/