使用节点但在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'});
'价值'被打印两次,这不是我所追求的。像这样继承可能不是寻找替代品/建议来处理这种钻石形状结构的最佳方式。
P.S。没有包含原始代码,但修改后希望简化 - 我已经手工完成了这个,不要认为有任何错误,但我想要解决的问题应该在那里。
答案 0 :(得分:1)
那是完全不可能的; Javascript不支持多重继承。
特别是,您不能拥有一个继承自两个原型的对象。
相反,您可以手动将原型中的所有功能复制到原型中。 (例如,使用mixin或extends方法)
答案 1 :(得分:1)
我不知道您对经典继承的依恋程度,但避免多重继承的一种方法(以及钻石继承问题)是使用 mixins (混入)。外行人:你把更多东西打到你的基类上,直到它完成你想要的一切。
答案 2 :(得分: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"
答案 3 :(得分: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');
再次感谢!