Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Наследование класса (https://javascript.ru/forum/misc/58866-nasledovanie-klassa.html)

WishMaster 14.10.2015 19:39

Наследование класса
 
Всем привет. ООП в Javascript начал изучать недавно, все делал по мануалам. Возникла проблема, которую я не понимаю, но возможно, местные гуру помогут решить этот вопрос. Имеется базовый класс Bote, и класс, который его расширяет - FreeBitcoinAccountController.
Код класса Bote:
function Bote() {
    this.accounts = {};
    //...остальной код...
    this.enabled = false;
}
Bote.prototype.init = function () {
    //... остальной код функции ...
    this.log('Бот загружен');
};


Код класса FreeBitcoinAccountController:
function FreeBitcoinAccountController() {
    //...остальной код...
    Bote.apply(this);
}
FreeBitcoinAccountController.prototype.init = function () {
    alert();//Bote.prototype.init.call(this);
    //...остальной код...
    this.main();
};
FreeBitcoinAccountController.prototype = Object.create(Bote.prototype);
FreeBitcoinAccountController.prototype.constructor = FreeBitcoinAccountController;


Далее создаю экземпляр класса, и вызываю метод init, но он почему-то вызывается из базового класса Bote, а не из FreeBitcoinAccountController. А когда переименовываю метод init в Bote, то вываливается ошибка, что метод не найден. Если я не ошибся, должно ведь происходить наследование класса, разве нет? И метод init должен вызываться из FreeBitcoinAccountController, даже если его нет в классе Bote (тем более, что класс Bote вообще не создается)

Decode 14.10.2015 19:49

WishMaster,
function Bote(name) {
    this.name = name;
}

Bote.prototype.init = function () {
    alert('Бот загружен ' + this.name);
};

function FreeBitcoinAccountController(name) {
    Bote.apply(this, arguments);
}

FreeBitcoinAccountController.prototype = Object.create(Bote.prototype);
FreeBitcoinAccountController.prototype.constructor = FreeBitcoinAccountController;

FreeBitcoinAccountController.prototype.init = function () {
    Bote.prototype.init.call(this);
};

var a = new FreeBitcoinAccountController('FreeBitcoin');

a.init();

WishMaster 14.10.2015 20:33

Блин, странно. Здесь код работает как надо. У меня же упорно не хочет выполняться переопределяемый метод init, который скрипт ищет в классе Bote вместо класса FreeBitcoinAccountController. Даже alert вставил, чтобы проверить, alert не выводится. Выполняется только из класса Bote.

Decode 14.10.2015 20:40

Цитата:

Сообщение от WishMaster
Алерт из init метода FreeBitcoinAccountController не выводится.

Наоборот.

Decode 14.10.2015 20:41

function Bote(name) {
  this.name = name;
}

Bote.prototype.init = function () {
  alert('bla-bla');
};

function FreeBitcoinAccountController(name) {
  Bote.apply(this, arguments);
}

FreeBitcoinAccountController.prototype = Object.create(Bote.prototype);
FreeBitcoinAccountController.prototype.constructor = FreeBitcoinAccountController;

FreeBitcoinAccountController.prototype.init = function () {
  Bote.prototype.init.call(this); // Bote
  alert('Бот загружен ' + this.name); // FreeBitcoin
};

var a = new FreeBitcoinAccountController('FreeBitcoin');

a.init();

WishMaster 14.10.2015 21:03

Да, я вижу, что здесь все работает правильно, но в моем коде почему-то та же самая конструкция уже не работает. Я обновил предыдущее сообщение, скопировал код в том варианте, как у меня он написан. Возможно, проблема в том, что код подгружается через JQuery, или у меня где-то ошибка.

ruslan_mart 14.10.2015 21:09

Расширять класс можно через __proto__:

FreeBitcoinAccountController.prototype.__proto__ = bote.prototype;

WishMaster 14.10.2015 21:21

Да, так тоже пробовал, все равно алерта нет. И в примерах по созданию классов вроде все точно так же описано, но почему-то выполняется код из Bote.init вместо FreeBitcoinAccountController.init. Я даже не понимаю, каким боком, ведь создается именно FreeBitcoinAccountController, Bote вообще не трогаю. И метод ищется именно в Bote, при присутствующем методе во FreeBitcoinAccountController пишет ошибку, если этого метода нет в Bote. А если есть, то выполняется только код из метода Bote.

ruslan_mart 14.10.2015 21:28

Вот тест:

function Bote() {
	
};
Bote.prototype.init = function() {
	alert('Bote');
};
Bote.prototype.test = function() {
	alert('Наследуемый метод от Bote');
};

function FreeBitcoinAccountController() {
	
};
FreeBitcoinAccountController.prototype.init = function() {
	alert('FreeBitcoinAccountController');
};
FreeBitcoinAccountController.prototype.__proto__ = Bote.prototype;

var f = new FreeBitcoinAccountController();
f.init();
f.test();

WishMaster 14.10.2015 21:33

Наверно, где-то у меня в коде ошибка.. У меня алерт не выводится в переопределенном методе. Было бы очень хорошо, если бы кто-нибудь помог с нахождением ошибки) Вот мой код
var Engine = {
    modules: {},
loadModule: function (module_data)
    {
        $.getScript('template/js/' + module_data.js_file, function () {
            eval('Engine.modules[module_data.type] = new ' + module_data.name + '();'); //создаем экземпляр класса FreeBitcoinAccountController (немного кривовато, но смысл в том, что все загружается динамически, в том числе имена классов)
            Engine.modules[module_data.type].init(); //вызываю метод init из созданного класса
        });
    }
}

//freebitcoin.js
function FreeBitcoinAccountController() {
    Bote.apply(this, arguments);
}
FreeBitcoinAccountController.prototype.init = function () {
    Bote.prototype.init.call(this);
    alert();//Alert не выполняется! как и дальнейший код
//код
    this.main();
};
FreeBitcoinAccountController.prototype = Object.create(Bote.prototype);
FreeBitcoinAccountController.prototype.constructor = FreeBitcoinAccountController;

//bote.js
function Bote() {
//код
}
Bote.prototype.init = function () {
    this.initContent();
//код
    this.log('Бот загружен');
};




P.S. Заменил
FreeBitcoinAccountController.prototype = Object.create(Bote.prototype);
FreeBitcoinAccountController.prototype.constructor = FreeBitcoinAccountController;

на
FreeBitcoinAccountController.prototype.__proto__ = Bote.prototype;

Теперь все работает. Но зачем же тогда в учебнике по созданию классов написан именно тот код, который был у меня изначально?


Часовой пояс GMT +3, время: 07:11.