Виртуальный класс а-ля Си Плас Плас
Здравствуйте хочу реализовать сабж в 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 "классов", но мне всё равно хочется узнать, как можно обойтись без создания экземпляра родительской функции-конструктора.. |
Цитата:
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]);
|
Да, я буду расширять, обязательно.
Так как ты указал я делал. Проблема возникает, когда я хочу сделать вот так: Class.prototype.p1 = "new value"; В этом случае свойство меняется у базового класса Interface, а мне нужно поменять прототип c одноимённым свойством только для Class. |
Цитата:
|
Voronar,
Короче, Class не обязан наследовать прототип Interface, он может иметь и свой собственный прототип. Тогда его экземпляры будут лазить за этим свойством именно в прототип родителя. А вообще, непонятны твои цели, что именно ты хочешь реализовать. Может в твоей задаче вообще классы не нужны. В JS Можно наследовать и напрямую от объектов. В любом случае, реализовать можно любую модель, как 2 пальца об асфальт. |
В "классе" Interface я хочу сделать чистые виртуальные функции, то есть аналог С++ ООП-интерфейса.
Когда я буду реализовывать эти функции в Class1, Class2 и Classn, то функции прототипа Interface будут каждый раз перетираться. А я хочу иметь реализации функций из Interface для каждого экземпляра Class1, Class2 и Classn, и чтобы у меня имелось только одно объявления функции для каждого класса. Можно описать эти классы по отдельности, но я хочу их наследовать от базового виртуального класса Interface. |
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, а я хочу обойтись минимальными затратами памяти. |
Цитата:
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]);
|
Цитата:
Я описал своё видение в примере, приведённом мной выше. Из моего примера видно, что для любого экземпляра Class1 или Class2, этот экземпляр будет иметь только одну реализацию функции в прототипе. То есть получается, что по-любому для каждого наследника нужно создавать экземпляр Interface. |
Цитата:
Что вы задумали то не имеет смысла. Пишите на этом языке, а не на том, который вы лучше знаете. В штатах люди живут годами после переезда и не говорят по-английски, так и вы собираетесь писать на js как в тылу врага. |
Цитата:
function inherits(Child, Parent) {
Child.prototype = Object.create(Parent.prototype, {
constructor: {
writable: true,
configurable: true,
enumerable: false
}
})
}
Вообще я бы посоветовал смотреть в сторону ES6, если хочется нормального ООП. Это еще неутвержденная спецификация Javascript, пока что на ней можно писать через компиляцию (спасибо kobezzza за ссылку).
class Parent {
constructor() {
}
method() {
}
}
class Child extends Parent {
static staticMethod() {
}
get getter() {
}
}
|
Цитата:
Interface=function(init){
var o={}
var base={
open: function(){console.log("virtual open")},
close: function(){console.log("virtual close")}
}
if(init){
o.open=init.open||base.open
o.close=init.close||base.close
}else{
o.open=base.open
o.close=base.close
}
return function(){return Object.create(o)}
}
Class1=Interface({open: function(){console.log("just open")}})
Class2=Interface({close: function(){console.log("just close")}})
Class3=Interface()
o1=Class1()
o2=Class2()
o3=Class3()
o1.open(); o1.close(); o2.open(); o2.close(); o3.open(); o3.close()
// just open
// virtual close
// virtual open
// just close
// virtual open
// virtual close
|
Цитата:
function Interface() {};
Interface.prototype.p1 = "property1";
function Class() {this.a=1; this.b=function(){alert(this.a)}};
Class.prototype = new Interface();
var obj = new Class();
alert([obj.p1, obj.a]);
obj.b()
|
Это ты не пизди, когда не знаешь.
Это не методы класса, это методы, присваемые инстансам класса при инициализации. При этом каждый новый инстанс будет иметь свою собственную пачку методов, что в большинстве случаев нецелесообразно и приводит к перерасходу памяти. Методы класса хранятся в прототипе. Кстати, с каких это пор ты стал употреблять ; и var? |
Цитата:
function Interface() {};
Interface.prototype.p1 = "property1";
function Class() {};
Class.prototype = Interface.prototype;
var obj = new Class();
Обсуждали уже в начале топика, ему надо чтобы изменение дочернего класса не влияло на Interface, идиот. А ты написал то же самое, только мудреным синтаксисом (чтоб никто не догадался опять?)
function inherits(Child, Parent) {
Child.prototype = Object.create(Parent.prototype, {
constructor: {
writable: true,
configurable: true,
enumerable: false
}
})
}
O=function(){}
O.prototype={a:1}
Child=function(){}
inherits(Child, O)
o=new Child
console.log(o.a)
Child.prototype.a=10
console.log(o.a)
o1=new Child
console.log(o1.a)
// 1
// 10
// 10
Не лезь в треды, где мужики разговаривают, пиши жеквери, это самое твое. |
Цитата:
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
Цитата:
Цитата:
|
Цитата:
|
И не буду, пример неверен. Надо так:
function inherits(Child, Parent) {
Child.prototype = Object.create(Parent.prototype, {
constructor: {
value: Child,
writable: true,
configurable: true,
enumerable: false
}
})
}
function Interface(){};
function Class(){};
inherits(Class, Interface);
Interface.prototype.someValue = 1;
Class.prototype.someValue = 2;
alert((new Interface()).someValue);
alert((new Class()).someValue);
|
Erolast,
Поправь код, у тебя ошибка там. Как поправишь, будем дальше смотреть. |
Пардон, поправил.
|
Erolast,
Че то я не догоняю, до конца, че там происходит. Ща некогда, потом подумаю. Отпишусь завтра. |
Сначала
Цитата:
|
Цитата:
|
Цитата:
P.S. Ну тут без меня началось... Я не встреваю в междусобойчик. |
Цитата:
Но ты таки присмотрись к ES6. |
Цитата:
Спасибо за пример реализации. Буду курить дальше. |
Цитата:
Цитата:
|
Цитата:
|
|
Цитата:
|
Цитата:
Object.create(Parent.prototype, {
constructor: {
Ну-ну |
Ещё такой вопрос. В новом стандарте есть какие-то коренные изменения, затрагивающие, например, механизм и структуру построения объектов. Все старые ухищрения будут работать или они уже не понадобятся?
|
Цитата:
|
Цитата:
|
Цитата:
|
Речь о том, что при применении new вызовется конструктор, а этого делать не надо, ибо в нем может быть
Цитата:
|
Цитата:
Используя конструктор, ты убиваешь сразу 2-х зайцев: создаешь объект с готовыми свойствами, и его прототип, и связь с этим прототипом. К тому же, это готовая фабрика. Object.create -- 'это заведомо более слабый вариант. Все что он делает -- создает объект с нужным прототипом(я тут не рассматриваю опционального аргумента -- это мелочь). Мы это могли бы делать и по старинке. {__proto__: example}, причем последняя даже лучше, поскольку в одном выражении можно создать и объект и св-ва без выкрутасов. |
| Часовой пояс GMT +3, время: 02:22. |