26.10.2014, 16:23
|
Кандидат Javascript-наук
|
|
Регистрация: 14.10.2014
Сообщений: 117
|
|
Сообщение от Erolast
|
Вот пока не догоняешь, помалкивал бы
|
Неохота мне щас парится, есть дела. Позже разберу. Не исключено, что там лажа, подозрительно выглядит. Но то что я сказал выше -- все правильно. Да ты и сам, понял, что обосрался. Аргументация "сам такой" -- это сильно, да. Поздравляю со сливом.
|
|
26.10.2014, 16:25
|
|
Профессор
|
|
Регистрация: 24.09.2013
Сообщений: 1,436
|
|
"Я нихера не понимаю, сейчас-то просто занят, да и вообще там лажа, да и вообще ты слил."
|
|
26.10.2014, 16:29
|
|
Быдлокодер;)
|
|
Регистрация: 19.11.2010
Сообщений: 4,338
|
|
Erolast, забей ты на этого нуба
|
|
26.10.2014, 16:31
|
Кандидат Javascript-наук
|
|
Регистрация: 14.10.2014
Сообщений: 117
|
|
Erolast,
Я тебе не за то говорил, а за последующие твои лажовые утверждения по-поводу расширения объекта. А к тому коду мы еще вернемся, не переживай.
|
|
26.10.2014, 16:32
|
|
Профессор
|
|
Регистрация: 24.09.2013
Сообщений: 1,436
|
|
|
|
04.11.2014, 12:18
|
Аспирант
|
|
Регистрация: 15.02.2013
Сообщений: 55
|
|
Возвращаемся к истинному сабжу. После обдумывания о концепции чистого виртуального класса а-ля C++, я пришёл к выводу, что на языке JavaScript такую концепцию не имеет смысла реализовывать, по крайней мере в таком виде.
Ещё раз повторю, что подразумевается под чистым виртуальным классом (ЧВК). ЧВК в C++ - это по сути реализация концепция ООП-интерфейсов. То есть мы объявляем ЧВК только в качестве описание для дальнейшей реализации только в наследуемых классах.
Например, создадим ЧВК IODevice и производные от него классы Device1 и Device2.
//C++ code:
#include <stdio.h>
#include <string>
class IODevice
{
protected:
std::string descriptor;
public:
virtual int open() = 0;
virtual ~IODevice() {}
};
class Device1 : public IODevice
{
public:
Device1(std::string _descriptor) //constructor
{
descriptor = _descriptor;
}
int open()
{
printf("%s opening...\n", descriptor.c_str());
return 0;
}
~Device1() {}
};
class Device2 : public IODevice
{
public:
Device2(std::string _descriptor) //constructor
{
descriptor = _descriptor;
}
int open()
{
printf("%s opening...\n", descriptor.c_str());
return 0;
}
};
int main()
{
Device1* dev1 = new Device1("Device1");
Device2* dev2 = new Device2("Device2");
//IODevice* dev = new IODevice(); //error: cannot allocate an object of abstract type 'IODevice'
dev1->open();
dev2->open();
delete dev2;
delete dev1;
return 0;
}
Можно запустить пример и убедиться, что для каждого класса запускается своя версия метода.
Возвращаюсь к JavaScript. Ведь нет смысла в том, чтобы создавать объект ("ЧВК"), только для того, чтобы просто иметь там свойства, которые по сути и не будут использоваться - это только расход памяти. Я вижу такую реализацию на JS:
"use strict";
Object.defineProperty(Object.prototype, "extends",
{
value: function(parent)
{
this.prototype = Object.create(parent.prototype,
{
constructor:
{
value: this,
writable: true,
configurable: true,
enumerable: false
}
});
arguments[1] === "INTERFACE" ? this.__interfaced__ = true : undefined;
},
enumerable: false,
writable: true,
configurable: true
});
function IODevice(fd)
{
if(this.constructor.hasOwnProperty("__interfaced__"))
{
this._descriptor = fd;
}
else
{
alert("Warning: cannot allocate an object of abstract type " + "\"" + this.constructor.name + "\"");
return new Error("Cannot allocate an object of abstract type " + "\"" + this.constructor.name + "\"");
}
}
function Device1(fd)
{
IODevice.call(this, fd);
}
Device1.extends(IODevice, "INTERFACE");
Device1.prototype.open = function()
{
console.log(this._descriptor + " opening...");
};
function Device2(fd)
{
IODevice.call(this, fd);
}
Device2.extends(IODevice, "INTERFACE");
Device2.prototype.open = function()
{
console.log(this._descriptor + " opening...");
};
var dev1 = new Device1("Device1");
var dev2 = new Device2("Device2");
var dev = new IODevice("dev");
dev1.open();
dev2.open();
console.log(dev);
|
|
04.11.2014, 13:49
|
|
Профессор
|
|
Регистрация: 24.09.2013
Сообщений: 1,436
|
|
Цитата:
|
Object.defineProperty(Object.prototype, "extends",
|
Определяй не для Object.prototype, а для Function.prototype. Этот метод применим только к функциям.
Задачу можно решить наследованием от объекта, а не от класса:
Object.defineProperty(Function.prototype, "extends", {
value: function(parent) {
*!*var inheritFrom = typeof parent == "function" ? parent.prototype : parent;*/!*
this.prototype = Object.create(inheritFrom, {
constructor: {
value: this,
writable: true,
configurable: true,
enumerable: false
}
});
},
enumerable: false,
writable: true,
configurable: true
});
var IODevice = {
};
function Device1() {}
Device1.extends(IODevice);
function Device2() {}
Device2.extends(IODevice);
new Device1();
new Device2();
new IODevice(); //TypeError: IODevice is not a constructor
В ES6 так:
var IODevice = {};
class Device1 prototype IODevice {
}
class Device2 prototype IODevice {
}
Последний раз редактировалось Erolast, 04.11.2014 в 13:54.
|
|
04.11.2014, 14:42
|
Аспирант
|
|
Регистрация: 15.02.2013
Сообщений: 55
|
|
А как в этом случае использовать конструктор абстрактного класса, если теперь это просто объект?
Ещё такой вопрос. Если мы передаём Object.create в качестве аргумента(proto) parent.prototype, то в этом случае реализуется наследование от функции-конструктора, а если просто объект parent, то в это случае мы получаем копию parent?
|
|
04.11.2014, 15:17
|
|
Профессор
|
|
Регистрация: 24.09.2013
Сообщений: 1,436
|
|
Цитата:
|
А как в этом случае использовать конструктор абстрактного класса, если теперь это просто объект?
|
Никак, нету никакого конструктора.
Цитата:
|
Ещё такой вопрос. Если мы передаём Object.create в качестве аргумента(proto) parent.prototype, то в этом случае реализуется наследование от функции-конструктора, а если просто объект parent, то в это случае мы получаем копию parent?
|
Object.create(otherObj) создает объект с внутренним свойством [[Prototype]] (доступным по геттеру __proto__), установленным на otherObj. При поиске свойства в объекте оно сначала ищется в самом объекте, затем в объекте, на который ссылается его внутреннее свойство [[Prototype]], затем в прототипе того объекта и так далее по цепочке, пока очередной прототип не окажется равным null.
Последний раз редактировалось Erolast, 04.11.2014 в 15:19.
|
|
04.11.2014, 16:17
|
Аспирант
|
|
Регистрация: 15.02.2013
Сообщений: 55
|
|
Сообщение от Erolast;
|
Никак, нету никакого конструктора.
|
Тогда твой вариант не подходит.
Сообщение от Erolast;
|
Object.create(otherObj) создает объект с внутренним свойством [[Prototype]] (доступным по геттеру __proto__), установленным на otherObj.
|
То есть в случае передачи parent.prototype свойства будут перебираться в прототипе функции-конструктора, а в случае передачи parent непосредственно в объекте функции-конструктора.
|
|
|
|