PDA

Просмотр полной версии : Вопрос по Робину Дебройлу (ООП)


Whatsername
20.11.2003, 16:05
Pet = function( name )
{
this.name = name;
}
Pet.prototype.legs = 4;
Pet.prototype.pet = true;

Dog = function( name ){

this.$_base = Pet;
this.$_base (name);
delete (this.$_base);

}
Dog.prototype.__proto__ = Pet.prototype;
Dog.prototype.price = 10;

rover = new Dog( "Rover" );

for(var i in rover){ trace( i + ":\t" + rover[i] ) }


Подскажите, пожалуйста, как rover получает свойство name.
Я не понимаю как работает:

this.$_base = Pet;
this.$_base (name);
delete (this.$_base);

Почему просто this.Pet (name); - не читает? Что передается в случае this.Pet (name); ?

Nox Noctis
20.11.2003, 16:20
зачем так хитро ? :)
Pet = function (name) {
this.name = name;
};
Pet.prototype.legs = 4;
Pet.prototype.pet = true;
Dog = function (name) {
Pet.apply(this, [name]);
};
Dog.prototype.__proto__ = Pet.prototype;
Dog.prototype.price = 10;
rover = new Dog("Rover");
for (var i in rover) {
trace(i+":\t"+rover[i]);
}
и вся эта заморочка с созданием и удалением this.$_base нужна была только для того чтобы в качестве this внутри функции Pet был тот же объект, который в качестве this внутри функции Dog.

Пушистик
20.11.2003, 16:26
Подскажите, пожалуйста, как rover получает свойство name.

наследование свойств от класса/создание надкласса:

Dog.prototype.__proto__ = Pet.prototype;

Почему просто this.Pet (name); - не читает? Что передается в случае this.Pet (name); ?

чё это ваще за синтаксис такой? :confused:

обычно чатаются свойства от созданных объектов на основе класса!
в данном случае - это rover!

trace(rover.legs);


после создания надкласса можно проверить что Dog получил все свойства:

myDog = new Dog();
trace(myDog.legs);



Я не понимаю как работает:

this.$_base = Pet;
this.$_base (name);
delete (this.$_base);



сам до конца не понимаю!:)определение надкласса как метода Dog с передачей аргумента - это понятно для чего!


но для чего потом delete (this.$_base); мне не понятно!:)

Пушистик
20.11.2003, 16:28
О!теперь понятно! :D

Whatsername
20.11.2003, 16:44
Nox Noctis и Пушистик - спасибо большое :)
Сейчас буду осмыслять...

Whatsername
20.11.2003, 19:22
Dear Nox Noctis и Пушистик,
если разбирать

this.$_base = Pet;
this.$_base (name);
delete (this.$_base);

1) rover получает свойство $_base со значением Pet (это что, правда такое значение может быть?)
2) rover вызывает метод Pet, передавая параметр name.
3) Pet навешивает на rover свойство name со значением параметра.
4) this.$_base удаляется как больше не нужный.

Верно?

Тогда почему нельзя написать просто this.Pet (name); ?

Nox Noctis
20.11.2003, 19:29
потому что в классе Dog НЕТУ такого метода - Pet...

я вообще-то не очень понимаю что имел в виду дебройль, написав такую запутку... не понятно зачем :) (можно цитату из книги ?)

получается что ты временно содаешь метод в объекте класса Дог, потом после его вызова тут же его удаляешь...

и при этом еще используешь прототип класса Pet как родительский для Dog... хотя только что использовал Pet как непонятно что, а не по оопшному назначению...

короче фигня какая-то.
все работает, это да, но нафига так ? :))

iLoveYou
20.11.2003, 19:55
ааа.. дебройлевские примеры "Жизнь вокруг нас"...
на вскидку:
Dog = function( name ){
this.$_base = Pet;
this.$_base (name);
delete (this.$_base);
}
Dog.prototype.__proto__ = Pet.prototype;
это есть вызов для данного объекта конструктора родительского класса с передачей ему параметра; свойство name в Pet назначается и наследуется объектом класса Dog при его создании.
все, конечно, очень условно, пример явно не слишком удачный. но это Дебройль -- -->обучение принципам. может, кто поправит?

Whatsername
20.11.2003, 20:00
Nox Noctis,
я вообще-то не очень понимаю что имел в виду дебройль, написав такую запутку... не понятно зачем :) (можно цитату из книги ?)

Примечание

Конструктор фактически ничего не знает о каждом конкретном экземпляре, однако он догадывается о том, что с помощью оператора new создается новый безымянный объект. Проще говоря, он "думает", что this указывает на некий объект, который будет создан.



Мы знаем, что this в конструкторе Dog указывает на его воплощение - rover (см. Примечание). Мы также знаем, что когда объект вызывает метод, this в методе указывает на вызывающий объект. Что нам мешает превратить Pat в метод экземпляра rover и запускать его оттуда? Другими словами, rover будет заключать в себе код конструктора Pet как одно из своих свойств и мы просто попросим rover запустить свой же метод. Давайте скажем это в третий раз: rover съел, проглотил Pet и теперь он внутри него, оттуда мы его и запустим. Теперь, когда метод(!) Pet запустится, this будет указывать на rover, поэтому все свойства, добавленные через this, добавляются к rover. Когда метод Pet отработает, он нам уже будет ни к чему, его смело можно удалить. Причем, нам совершенно не обязательно называть его Pet, его код должен быть таким же, а имя может быть любым. Таким любым, что вы должны быть абсолютно уверены в том, что нигде его не используете в программе как свойство объекта, ведь мы его совсем скоро удалим. Вполне подойдет имя $_base (просто base не подойдет, иначе все ваши base будут лежать в мусорной корзине).

и при этом еще используешь прототип класса Pet как родительский для Dog... хотя только что использовал Pet как непонятно что, а не по оопшному назначению...

Pet - я еще использую как, типа, метод для экземпляров Dog.

iLoveYou
20.11.2003, 20:06
да, я не мог сказать так красноречиво, как Дебройль =))))
то, что написано, по-моему, все объясняет и раскладывает по полочкам.
dm_nev, может, мы тебе с чем-то конкретным поможем? какая проблема-то? :)

Nox Noctis
20.11.2003, 20:09
2Sergey"iLoveYou"
сергей, с примером уже разобрались давно :)
вопрос только зачем он такой странный :)

2dm_nev
аа... ну вот. я тебе это и сказал только не так подробно...

но, имхо, этот пример все только запутывает...
я думаю надо было показать наследование отдельно а вписывание методов отдельно...
(хотя кто я такой чтобы ему советовать :)) )

Whatsername
20.11.2003, 20:15
все объясняет и раскладывает по полочкам.

Sergey"iLoveYou", если бы у меня все полочки лежали на своих полочках, то я бы ни спрашивал ни про какие ООПолочкины структуры ;)

Я что-то совсем запутался... :eek: Скажите просто что делает строчка
this.$_base = Pet;
Может кофе выпить?

Whatsername
20.11.2003, 20:24
2 Nox Noctis, уже разобрались?
потому что в классе Dog НЕТУ такого метода - Pet...
Разве this в классе Дог указывает не на экземпляр (rover), разве этот экземпляр не может вызвать метод Pet?

Nox Noctis, я понимаю, что у тебя чувство, будто ты седьмой раз мне одно и тоже повторяешь, но я ей-ей не понимаю.

Whatsername
20.11.2003, 21:16
Ребята, тут все это знают, но я скажу еще раз:
this.$_base = Pet;
$_base получает метод Pet, иначе этот метод не вызвать.
Все верно?
Спасибо большое :D

Nox Noctis
20.11.2003, 22:20
хмм... ну все же написано уже :)
а у дебройля вообще длинно и подробно разжевано...

смотри:
Pet = function (name) {
trace("test : "+this+" : "+this.test);
};
Dog = function (name) {
trace("is Pet function here ? "+(Pet ? "yes" : "no"));
Pet();
trace("is this.Pet function here ? "+(this.Pet ? "yes" : "no"));
this.Pet();
};
Dog.prototype.test = "this is a Dog class member";
rover = new Dog("Rover");убрали все лишнее..

в конструкторе Дог смотрим видна ли функция (ЭТО НЕ МЕТОД) Pet в данной области видимости имен. потом проверяем то же самое для this.Pet...

this.Pet естесственно не видна. если бы мы сделали так:
Pet = function (name) {
trace("test : "+this+" : "+this.test);
};
Dog = function (name) {
trace("is Pet function here ? "+(Pet ? "yes" : "no"));
Pet();
trace("is this.Pet function here ? "+(this.Pet ? "yes" : "no"));
this.Pet();
};
Dog.prototype.test = "this is a Dog class member";
Dog.prototype.Pet = Pet
rover = new Dog("Rover");то все бы заработало. потому что мы добавили к классу Дог МЕТОД Pet.

а в примере дебройля именно это и происходит.. мы добавляем к экземпляру класса Дог метод Пет.. просто потом его сразу удаляем после использования.

iLoveYou
20.11.2003, 22:43
Nox, понятно :)
меня пример смутил наличием Dog.prototype.__proto__ = Pet.prototype;
вопрос, оказывается, в другом был. :)

Whatsername
21.11.2003, 11:25
Спасибо большое, Nox Noctis ты мне очень помог. Я наконец-то понял как это работает. Метод - просто свойство, принадлежащее классу, иначе он (метод) работать не будет.
Хотя я встречал исходники, где определяется функция (метод), а потом к ней (к нему) обращаются все кто захочет - любые переменные.
Например в первом кадре определяется метод formatbytes (bytes); для форматирования bytes в дружественный размер (57 Kb, 1.3 Mb), а во втором кадре левая переменная, содержащая getBytesLoaded (); обращается к formatbytes (bytes); и все работает! Это не против правил ООП? Ведь переменная, содержащая getBytesLoaded (); не имеет метода formatbytes (); в своем свойстве.
Если я что-то напутал, то я уверен, что все равно соображу - рано или поздно. А вот если ты уже засыпаешь читая мои вопросы - забудь. Спасибо большое. :)

Nox Noctis
21.11.2003, 11:40
Оригинал написал(а) dm_nev
Метод - просто свойство
Оригинал написал(а) dm_nev
обращаются - любые переменные

что-что, простите ? http://demonscity.combats.ru/i/smile/rotate.gif
ладно фиг с ними с формулировками, главное чтобы ты сам понимал что сказал :))

методом называется функция, ссылка на которую хранится внутри объекта. блягодаря тому что она вызывается из объекта, указатель this указывает на объект из которого она вызвана.

но функция может и не быть привязана к объекту. можно вызывать функцию саму по себе.
например проверь:
test = function () {
trace(this);
};
id = setInterval(test, 500);
в аутпуте будет undefined. потому что функция вызвана НЕ как метод.

если ты определяешь функцию без указания объекта в котором ее прописываешь, то она автоматически становится МЕТОДОМ того мувиклипа в котором находится код.
например, если напишем в руте:
function test () {
// ...
}
то тест станет методом рута. и this внутри нее будет указывать на _левел0

Whatsername
24.11.2003, 19:00
Dear Nox Noctis, я решил больше ничего не писать в этом топике пока не стану супер ООПером (ужас), чтобы не нервировать тебя и людей, незаслуживающих такого непонимания с моей стороны...
Спасибо большое тебе (и не только тебе)... ребята, наверное мне нужно больше почитать книг "мы купили комьютер" или "видоус для чайников", так как я пребываю в полной уверенности, что this в методе DOG указывает на rover (будущий экземпляр DOG), и будучи полноценным экземпляром - может вызывать методы, в том числе PET.
Спасибо ребята, я все распечатал и обязательно осилю - ваша помощь не напрасна :)

Nox Noctis
24.11.2003, 19:07
гррррр... :))

в этом примере
ПЕТ ЭТО НЕ МЕТОД КЛАССА ДОГ
понимаешь ? :)
в описании класса нету такого метода.

его ВРЕМЕННО делают методом объекта РОВЕР
(в результате чего, как ты и сказал, this внутри Pet'а указывает на ровера)

но если бы этого не сделали
(всей этой ботвы с переменной $_base)
то внутри Pet'а this указывал бы на _level0, где и прописан изначально...

Whatsername
26.11.2003, 10:56
Ага, Nox Noctis, именно поэтому в прототипе класса нужно указывать методы к которым экземпляры этого класса могут обращаться?
Иначе для в каждом классе придется создавать такой вот $_base...

Whatsername
26.11.2003, 16:11
Я понял:
у Ровера нет ПЕТ
У this в ДОГе нет ПЕТ
словом - у ДОГа нет ПЕТ. (именные пространства (область видимости), это так называется?)
Боже, как хорошо, что у ДОГа нет ПЕТ :D
Спасибо, Nox Noctis, сила_твоего_духа = истина; :D
Спасибо.

Nox Noctis
26.11.2003, 18:41
настоящий джыдай :)
да пребудет с тобой Сила... :)

Whatsername
27.11.2003, 19:19
Nox Noctis, я сегодня получил ответ от Дебройля :eek:
Посмотри-ка: полный undefined :confused:


When you call Guru from the Pro class, it returns the result to the pro instance, but the 'this' in Pro is not the same as the 'this' in Guru. One represents the 'Pro' instance, the other the 'Guru' instance. So you could say


Guru = function (name) {
this.name = name;
}
Pro = function (name){
this.guru1 = Guru(name);
}
p = new Pro("test");
trace(p.guru1.name); // test

If you wan't those classes to be related, you have to use inheritance. Then Pro would inherit from Guru, and it would look something like:

Guru = function (name) {
this.name = name;
}
Pro = function (name){
super(name);
}
Pro.prototype.__proto__ = Guru.prototype;
Pro.prototype.__constructor__ = superclass;

p = new Pro("test");
trace(p.name); // test

Hope you are keeping warm this winter - not sure what part of Russia you are in... It has been too warm here this year (Manitoba Canada), we only got our ice rink finished today : (.

Cheers,
Robin

Nox Noctis
27.11.2003, 19:38
ну вооот :) все то же самое... тлько тут он еще дополнил примером с super()

вот это как раз правильное наследование.

а вариант когда функцию делают методом - это тоже способ добиться того же результата, но никакого там наследования нет :)

в книге он немного смешал оба варианта... то есть наследование и "не-наследование" :)

Whatsername
27.11.2003, 21:18
Guru = function (name) {
this.name = name;
}
Pro = function (name){
this.guru1 = Guru(name);
}
p = new Pro("test");
trace(p.guru1.name); // undefined а не test

Nox Noctis
28.11.2003, 00:53
ааа... ты вот о чем...
у блин :) а я в конце рабочего дня не понял нифига..
похоже, тут маэстро слегка лажанулся...

когда пишешь то что хорошо знаешь, очень лениво проверять что написал, это понятно :))

я думаю, он хотел сказать так:

Guru = function (name) {
this.name = name;
}
Pro = function (name){
this.guru1 = new Guru(name);
}
p = new Pro("test");
trace(p.guru1.name); // test

вобщем, видимо приморозило его слегка :)

Nox Noctis
28.11.2003, 01:10
и с супером он тоже того... мимо кассы... :)

super без указания имени метода должен вызвать такой же метод в над-классе... то есть в над-классе, в его коде, должен бы вызваться метод Guru.prototype.Pro... но его там, увы, нет :)
Guru = function () {
};
Guru.prototype.ad_astra = function(name) {
this.name = "Guru : "+name;
};
Pro = function (name) {
super.ad_astra(name);
trace(this.name);
this.ad_astra(name);
trace(this.name);
};
Pro.prototype.ad_astra = function(name) {
this.name = "Pro : "+name;
};
Pro.prototype.__proto__ = Guru.prototype;
Pro.prototype.__constructor__ = Guru;
p = new Pro("test"); ...это иллюстрация работы super()

как врубишься - отправь ему ответ с комментариями :) а то вдруг мы не догнали какой-то хитрой задумки на самом деле... :))

Whatsername
28.11.2003, 10:47
Да, Nox Noctis, обязательно сообщу о результатах.
Во как бывает, ё-моё :D

Whatsername
03.12.2003, 14:13
Nox Noctis, теперь Он тоже знает как это работает :)
Sorry typo : ). It should be
this.guru1 = new Guru(name);

That is is you want composition. If you want inheritance, you should probably use the second method, or use the following function:

Function.prototype.raExtends = function (superclass)
{
this.prototype.__proto__ = superclass.prototype;
this.prototype.__constructor__ = superclass;
ASSetPropFlags(this.prototype, ["__constructor__"], 1);
}

..and then say:

Pro.raExtends(Guru);

If you use 'new' there are a few problems, mostly it runs the superclass constructor while defining methods.

Nox Noctis
03.12.2003, 18:28
ну вот, сразу видно человек опохмелился правильно :)))

Whatsername
03.12.2003, 18:31
нет для тебя авторитетов :D