Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Виртуальный класс а-ля Си Плас Плас (https://javascript.ru/forum/misc/51128-virtualnyjj-klass-lya-si-plas-plas.html)

Voronar 24.10.2014 21:33

Виртуальный класс а-ля Си Плас Плас
 
Здравствуйте хочу реализовать сабж в JS.
Есть вот такой код:
function Interface() {};
Interface.prototype.p1 = "property1";

function Class() {};
Class.prototype = new Interface();

var obj = new Class();
console.log(obj.p1);


Так всё работает как надо, но у меня есть один вопрос. Почему в свойстве prototype "класса наследника" Class нужно указывать именно экземпляр функции-конструктора Interface, а не саму функцию-конструктор. А то получается, что нужно сначала потратить память для создания объекта, а потом уже только я получаю возможность "наследования". А если я буду наследовать 20 "классов"?

#1 В принципе, можно использовать один созданный объект для этих 20 "классов", но мне всё равно хочется узнать, как можно обойтись без создания экземпляра родительской функции-конструктора..

terminator-101 24.10.2014 22:32

Цитата:

Сообщение от Voronar
А то получается, что нужно сначала потратить память для создания объекта, а потом уже только я получаю возможность "наследования".

Короче, за пвмять особо не беспокойся. Так как на твой объект никто не ссылается, его загребет GC, но если это тебя беспокоит, можешь сделать вот так
function Interface() {};
Interface.prototype.p1 = "property1";
 
function Class() {};
Class.prototype = Interface.prototype
 
var obj = new Class();
alert(obj.p1);

Толко это не прокатит, если ты хочешь сделать Class реально наследником Interface, а не только наследовать от его прототипа. Но в твоем случае и так сойдет. То что ты написал, имеет смысл, только если
function Interface() {this.a=1; this.b=2};
Interface.prototype.p1 = "property1";
 
function Class() {};
Class.prototype = new Interface
 
var obj = new Class();
alert([obj.p1, obj.a, obj.b]);

Voronar 24.10.2014 22:40

Да, я буду расширять, обязательно.
Так как ты указал я делал. Проблема возникает, когда я хочу сделать вот так:
Class.prototype.p1 = "new value";

В этом случае свойство меняется у базового класса Interface, а мне нужно поменять прототип c одноимённым свойством только для Class.

terminator-101 24.10.2014 22:46

Цитата:

Сообщение от Voronar
В этом случае свойство меняется у базового класса Interface, а мне нужно поменять прототип c одноимённым свойством только для Class.

Ну так указывай тогда этот прототип только для Class, нахрен ты на Interface его вешаешь?

terminator-101 24.10.2014 22:58

Voronar,
Короче, Class не обязан наследовать прототип Interface, он может иметь и свой собственный прототип. Тогда его экземпляры будут лазить за этим свойством именно в прототип родителя. А вообще, непонятны твои цели, что именно ты хочешь реализовать. Может в твоей задаче вообще классы не нужны. В JS Можно наследовать и напрямую от объектов. В любом случае, реализовать можно любую модель, как 2 пальца об асфальт.

Voronar 24.10.2014 23:03

В "классе" Interface я хочу сделать чистые виртуальные функции, то есть аналог С++ ООП-интерфейса.
Когда я буду реализовывать эти функции в Class1, Class2 и Classn, то функции прототипа Interface будут каждый раз перетираться. А я хочу иметь реализации функций из Interface для каждого экземпляра Class1, Class2 и Classn, и чтобы у меня имелось только одно объявления функции для каждого класса.
Можно описать эти классы по отдельности, но я хочу их наследовать от базового виртуального класса Interface.

Voronar 24.10.2014 23:13

function Interface() {};
Interface.prototype.fd = "file descriptor";
Interface.prototype.open = "virtual function";
Interface.prototype.close = "virtual function";


function Class1() {};
function Class2() {};
Class1.prototype = new Interface();
Class2.prototype = new Interface();

Class1.prototype.open = function()
{
    alert("open1");
};
Class1.prototype.close = function()
{
    alert("close1");
};

Class2.prototype.open = function()
{
    alert("open2");
};
Class2.prototype.close = function()
{
    alert("close2");
};

var obj1 = new Class1();
var obj2 = new Class2();
obj1.open();
obj2.open();


Работает так, как я хочу, но в итоге мне нужно создавать для каждого наследника новый экземпляр Interface, а я хочу обойтись минимальными затратами памяти.

terminator-101 24.10.2014 23:19

Цитата:

Сообщение от Voronar (Сообщение 337421)
В "классе" Interface я хочу сделать чистые виртуальные функции, то есть аналог С++ ООП-интерфейса.
Когда я буду реализовывать эти функции в Class1, Class2 и Classn, то функции прототипа Interface будут каждый раз перетираться. А я хочу иметь реализации функций из Interface для каждого экземпляра Class1, Class2 и Classn, и чтобы у меня имелось только одно объявления функции для каждого класса.
Можно описать эти классы по отдельности, но я хочу их наследовать от базового виртуального класса Interface.

Не знаю, что там в ++, но похоже на это.
function Interface() {}; 
Interface.prototype.p1 = "property1";
 
function Class(prop) {if(prop) this.p1=prop};
Class.prototype = new Interface
 
o1=new Class();
o2=new Class("foo")
alert([o1.p1, o2.p1]);

Voronar 24.10.2014 23:31

Цитата:

Сообщение от terminator-101 (Сообщение 337423)
Не знаю, что там в ++, но похоже на это.
function Interface() {}; 
Interface.prototype.p1 = "property1";
 
function Class(prop) {if(prop) this.p1=prop};
Class.prototype = new Interface
 
o1=new Class();
o2=new Class("foo")
alert([o1.p1, o2.p1]);

Может я ошибаюсь, но мне кажется, что в этом случае функция(объект), имя которой ты передаёшь как параметр конструктора, будет создаваться для каждого экземпляра (так как ты используешь this), а это слишком затратно.
Я описал своё видение в примере, приведённом мной выше.
Из моего примера видно, что для любого экземпляра Class1 или Class2, этот экземпляр будет иметь только одну реализацию функции в прототипе. То есть получается, что по-любому для каждого наследника нужно создавать экземпляр Interface.

kostyanet 25.10.2014 03:23

Цитата:

Сообщение от Voronar
А если я буду наследовать 20 "классов"?

Кавычки поставили позже, на 2 слова раньше надо.

Что вы задумали то не имеет смысла. Пишите на этом языке, а не на том, который вы лучше знаете. В штатах люди живут годами после переезда и не говорят по-английски, так и вы собираетесь писать на js как в тылу врага.


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