То, что вы описываете как «компонент», чаще называют классом. То, что вы описываете как «воспитание», чаще всего называется наследованием. Вы в курсе об иерархии классов:)
Итак, ваш базовый класс в Item
. Этот предмет будет иметь основные атрибуты, которыми должны обладать все предметы в вашем игровом мире. Все объекты в вашем игровом мире будут наследоваться от Предмета.
A Weapon
- это предмет. A MagicalItem
это пункт. A LegendaryItem
это предмет. Эти три класса являются подклассами Item.
Все становится немного сложнее, когда вы хотите LegendaryMagicalWeaponItem
. В этом суть вашего вопроса: возможно ли множественное наследование в JavaScript?
Если перефразировать Святых из Бундока, вам не нужно множественное наследование, если вы абсолютно не уверены, что оно вам нужно. Зачем? Это быстро приводит к осложнениям. Например, что если два суперкласса имеют метод или атрибут с одинаковым именем? Что если они наследуются от двух разных базовых классов, и один из этих классов вызывает конфликт имен? Вы можете видеть, куда это идет.
К счастью, JavaScript, как и Python, является очень гибким языком. Вы не обязаны использовать множественное наследование или даже интерфейсы для обобщения поведения разнородных объектов.
Допустим, MagicalItem
имеет свойство mana
, а LegendaryItem
имеет метод legacy()
. Допустим, объект оружия имеет damage
. Допустим, Item
имеет важные физические атрибуты и набор физических методов; это явно «доминирующий» суперкласс. Ничто не мешает вам сделать это:
// Base classes
function Item() {
// some default values...
}
Item.prototype.physics = function (t) {/* physics stuff */}
function Magical(mana) {
this.mana = mana;
}
function Weapon(damage) {
this.damage = damage;
}
function Legendary(legacy) {
this.legacy = function () {return legacy;};
}
// Actual world item class
function MyLegendaryMagicalSword(x,y) {
this.x = x;
this.y = y;
Weapon.call(this, MyLegendaryMagicalSword.DAMAGE);
Legendary.call(this, MyLegendaryMagicalSword.LORE);
Magical.call(this, MyLegendaryMagicalSword.START_MANA);
}
// actual prototypal inheritance
MyLegendaryMagicalSword.prototype = new Item();
// class attributes
MyLegendaryMagicalSword.DAMAGE = 1000;
MyLegendaryMagicalSword.START_MANA = 10;
MyLegendaryMagicalSword.LORE = "An old sword.";
// Sword instance
var sword = new MyLegendaryMagicalSword(0, 0);
sword.physics(0);
sword.mana;
sword.legacy();
// etc
// probe object for supported interface
if (sword.hasOwnProperty("damage")) {
// it's a weapon...
}
Это простой и грязный способ сделать то, что вы описываете.
> sword
{ x: 0,
y: 0,
damage: 1000,
legacy: [Function],
mana: 10 }