5

使用节点但在 JavaScript 中寻找钻石继承的方法:

var util = require('util');

function Base(example_value) {
  console.log(example_value);
  this.example_property = example_value;
  this.example_method = function() { ... };
}

function Foo(settings) {
  var f = settings.f;
  Base.call(x);
  this.settings = settings;
}

util.inherits(Foo, Base);

function Bar(settings) {
  var b = settings.b;
  Base.call(b);
  this.settings = settings;
}

util.inherits(Bar, Base);

var foo = new Foo({f: 'bar'});
// 'bar' gets printed and I can call methods from Base..
foo.example_method();
var bar = new Bar({b: 'foo'});
// 'foo' gets printed and I can call methods from Base..
bar.example_method();

这里没有问题..但是我需要在另一个无所不包的对象中制作 Foo 和 Bar(和 Base)中可用的所有内容:

function Top(settings) {
  Foo.call(this, settings);
  Bar.call(this, settings);
}

util.inherits(Top, Foo);
util.inhertis(Top, Bar);

var top = new Top({some: 'value'});

'value' 被打印两次,这不是我想要的。像这样进行继承可能不是最好的方法,因此寻找替代方案/建议来处理这种菱形结构。

PS 没有包含原始代码,但经过修改以希望简化 - 我是手工完成的,不认为有任何错误,但我想要解决的问题应该在那里。

4

4 回答 4

1

可以使用委托吗?

function Top(settings) {
  this.foo = new Foo(settings);
  this.bar = new Bar(settings);
}

Top.prototype.conflictingMethod = function() {
   // use either this.foo or this.bar
}
Top.prototype.anotherMethod = function() {
   return this.foo.anotherMethod();
}

你也可以使用 mixins,但你需要将它添加到你的类系统中。Ext-JS 支持 mixins http://www.sencha.com/learn/sencha-class-system

// My/sample/CanSing.js
Ext.define('My.sample.CanSing', {
    sing: function(songName) {
        alert("I'm singing " + songName);
    }
});

// My/sample/CanPlayGuitar.js
Ext.define('My.sample.CanPlayGuitar', {
    playGuitar: function() {
        alert("I'm playing guitar");
    }
});

// My/sample/CanComposeSongs.js
Ext.define('My.sample.CanComposeSongs', {
    composeSongs: function() {
        alert("I'm composing songs");

        return this;
    }
});

// My/sample/CoolGuy.js
Ext.define('My.sample.CoolGuy', {
    extend: 'My.sample.Person',
    mixins: {
        canSing: 'My.sample.CanSing',
        canPlayGuitar: 'My.sample.CanPlayGuitar'
    }
});

// My/sample/Musician.js
Ext.define('My.sample.Musician', {
    extend: 'My.sample.Person',
    mixins: {
        canSing: 'My.sample.CanSing',
        canPlayGuitar: 'My.sample.CanPlayGuitar',
        canComposeSongs: 'My.sample.CanComposeSongs'
    }
});

// app.js
var nicolas = new My.sample.CoolGuy("Nicolas");
nicolas.sing("November Rain"); // alerts "I'm singing November Rain"
于 2013-05-13T16:33:17.790 回答
1

感谢所有有效的答案,我会投票。我已经整理了一个更有用和真实世界的示例,它似乎可以完成这项工作,所以我在这里提供了一个答案,但看起来有很多方法可以做到这一点:

function TXObject(settings) {
  this.transmit = function(data) {
    // Transmit data using settings
    console.log('Transmitting data: ' + data);
  }
}

function RXObject(settings) {
  this.receive = function(data) {
    // Receive data using settings
    console.log('Receiving data: ' + data);
  }
}



function Device(settings) {
  this.settings = settings;
}

Device.prototype.asTransmitter = function() {
  var txInstance = new TXObject(this.settings);
  this.transmit = txInstance.transmit.bind(txInstance);
  // Alternatively to wrap txInstance.transmit and add functionality..
  // this.transmit = function() { txInstance.transmit(...); }
  return this;
}

Device.prototype.asReceiver = function() {
  var rxInstance = new RXObject(this.settings);
  this.receive = rxInstance.receive.bind(rxInstance);
  // Same thing for receive..
  // this.receive = function() { rxInstance.receive(...); }
  return this;
}

Device.prototype.asTransceiver = function() {
  this.asTransmitter();
  this.asReceiver();
  return this;
}

var d = new Device({foo: 'bar'});
console.log(d);
var tx = new Device({foo: 'bar'}).asTransmitter();
console.log(tx);
var rx = new Device({foo: 'bar'}).asReceiver();
console.log(rx);
var txrx = new Device({foo: 'bar'}).asTransceiver();
console.log(txrx);

tx.transmit('hello');
rx.receive('world');

txrx.transmit('hello');
txrx.receive('world');

再次感谢!

于 2013-05-14T20:32:59.980 回答
1

那是完全不可能的;Javascript 不支持多重继承。

特别是,您不能拥有从两个原型继承的单个对象。

相反,您可以手动将两个原型中的所有功能复制到您的原型中。(例如,使用 mixin 或 extends 方法)

于 2013-05-13T16:28:11.160 回答
1

我不知道您对经典继承的依恋程度如何,但避免多重继承(以及菱形继承问题)的一种方法是使用mixins(混入)。通俗地说:你在你的基类上添加更多的东西,直到它完成你想要的一切。

于 2013-05-13T16:28:54.697 回答