LINUX.ORG.RU

Объясните как наследовать

 , ,


0

1

Решил вот немного поковыряться в NodeJS. Встал вопрос как там дела с ООП. Допустим, мне нужно создать класс A, потом породить от него класс B, которые будет содержать и методы класса A и методы класса B. Как это правильно сделать?

function classA() {
	this.printInfo = function () {
		console.log("I am classA.");
	}
}

function classB() {
	this.printMoreInfo = function () {
		console.log("I am classB.");
	}
}

classB.prototype = classA;

var obj = new classB();

obj.printMoreInfo();
obj.printInfo();

Вот такое валится с ошибкой на вызове printInfo.

★★★★★

Последнее исправление: cetjs2 (всего исправлений: 1)

С наследованием всё вроде правильно, только методы надо объявлять так:

ClassA.prototype.printInfo = function() { console.log("I'm ClassA."); }

Kalashnikov ★★★
()
Ответ на: комментарий от Kalashnikov

сделал так:

function classA() {
	
}

classA.prototype.printInfo = function () {
	console.log("I am classA.");
}

function classB() {
	this.printMoreInfo = function () {
		console.log("I am classB.");
	}
}

classB.prototype = classA;

var obj = new classB();

obj.printMoreInfo();
obj.printInfo();

Ошибка та же.

KivApple ★★★★★
() автор топика
Ответ на: комментарий от KivApple

А каков текста ошибки?

var A, B, instance_of_B;

A.prototype.printInfo = function() { alert('A'); };

B.prototype = A;

B.prototype.printInfo = function() { alert('B'); };

instance_of_B = new B();

instance_of_B.printInfo();

outtaspace ★★★
()

дык ты конструктор classA не вызвал. поэтому рантайм не знает что у класса classA есть метод printInfo(). вот и валится.

outtaspace ★★★
()

function classA() {
	this.printInfo = function () {
		console.log("I am classA.");
	}
}

function classB() {
	this.printMoreInfo = function () {
		console.log("I am classB.");
	}
}

classB.prototype = new classA(); // тут суть

var obj = new classB();

obj.printMoreInfo();
obj.printInfo();

Всё правильно outtaspace сказал: не вызван конструктор classA. Ты пытаешься сделать наследование от конструктора, а в JavaScript наследование от существующих объектов.

Решил вот немного поковыряться в NodeJS.

Если не считать того, как там реализован поток выполнения, то это обычный ДжаваСкрипт.

Если есть отдельные вопросы - советую курить Фланагана. Могу поделиться хорошей ПДФкой.

sphericalhorse ★★★★★
()
Ответ на: комментарий от sphericalhorse

Вот так получилось:

function classA() {
	this.printInfo = function () {
		console.log("I am classA.");
	}
}

function classB() {
	this.__proto__();
	this.printMoreInfo = function () {
		console.log("I am classB.");
	}
}

classB.prototype = classA;

var obj = new classB();

obj.printMoreInfo();
obj.printInfo();

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

KivApple ★★★★★
() автор топика
Ответ на: комментарий от KivApple

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

function classA() {
	this.printInfo = function () {
		console.log("I am classA.");
	}
}

function classB() {
	this.__proto__();
	this.printInfo = function () {
		this.__proto__.printInfo();
		console.log("I am classB.");
	}
}

classB.prototype = classA;

var obj = new classB();

obj.printInfo();

KivApple ★★★★★
() автор топика
Ответ на: комментарий от KivApple

Уже говорилось что надо выполнить classB.prototype = new classA();

__proto__ — проприетарщина, не надо использовать.

Все выражения завершай точкой с запятой. Например в конструкторе classB у тебя создается свойство printMoreInfo как «function expression», и это выражение надо завершить точкой с запятой.

Выноси лишнее из функций являющихся конструкторами - объявления свойств и их инициализация в конструкторе приемлемы, а объявления методов лучше вынести наружу.

Используй JSLint (с нодой хорошо дружит) для выявления потенциальных проблем.

outtaspace ★★★
()
Ответ на: комментарий от KivApple

Трогать __proto__ - это быдлокод. Конструктор родителя надо вызывать когда указываешь прототип потомка (выше ж поправили). Ну и методы лучше добавлять прототипу, а не каждому объекту в конструкторе.

function classA() {}

classA.prototype.printInfo = function () {
	console.log("I am classA.");
}


function classB() {}

classB.prototype = new classA();    // тут суть (с)
classB.prototype.printMoreInfo = function () {
	console.log("I am classB.");
}

var obj = new classB();

obj.printMoreInfo();
obj.printInfo();
Kalashnikov ★★★
()
Ответ на: комментарий от KivApple

// все наше приложение ассоциируется с одной, единственной, переменной в глобальном Scope

var my_app = {};

my_app.A = function() {}; // конструктор A

my_app.A.prototype.printInfo = function() { window.console.log('I am classA.'); };

my_app.B = function() {}; // конструктор B

my_app.B.prototype = new my_app.A(); // тут говорим что прототипом B является _объект_ A

my_app.B.prototype.printMoreInfo = function() { window.console.log('I am classB.'); };

(function() {

var instance_of_B = new my_app.B();

instance_of_B.printInfo();

instance_of_B.printMoreInfo();

} )();

outtaspace ★★★
()
Ответ на: комментарий от sphericalhorse

Кто-то может объяснит что не так в том коде, который я предложил?

sphericalhorse ★★★★★
()
Ответ на: комментарий от sphericalhorse

Везде она нужна, хотя бы потому что в любом месте может оказаться что-нибудь типа (new Class()).method() или замыкание и если у предыдущей строки нет точки с запятой, оно распарсится как вызов предыдущего выражения. Такое иногда только после пары часов лютого тупняка можно отловить.

Ну и культура программирования, всё такое...

Kalashnikov ★★★
()
Ответ на: комментарий от sphericalhorse

Ну, третий я и описал. Один он раскладывается на весь код если только ты не гений с первого раза пишущий идеальный код который не требует фиксов и добавления функционала.

А ретёрн ты походу путаешь с фичей со скобками/переносом строки.

//...
return
{
    "property": value,
}
Kalashnikov ★★★
()
Ответ на: комментарий от Kalashnikov

Сделал. Однако столкнулся с проблемой, что новый объект не видит свойств родителя.

Например,

function classA() {
	this.text = "Ok!";
}

classA.prototype.printInfo = function () {
	console.log(this.text);
	console.log("I am classA.");
}


function classB() {}

classB.prototype = new classA();
classB.prototype.printMoreInfo = function () {
	console.log("I am classB.");
}
classB.prototype.printInfo = function() {
	console.log("Overloaded function.");
	this.constructor.prototype.printInfo();
}

var obj = new classB();

obj.printMoreInfo();
obj.printInfo();

Вместо «Ok» выводит «undefined».

KivApple ★★★★★
() автор топика
Ответ на: комментарий от KivApple

И это, черт возьми, предсказуемо.

Не надо тащить ООП в JavaScript.
</thread>

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.