2016-12-19 11 views
1

私のプロジェクトでは、JavaScriptプロトタイプを継承するために使用しています。私はスーパータイプ(車のような)と多くのサブタイプ(アウディ/メルセデス/ ...)を持っています。すべての車のブランドは、非常に巨大なタイプの「ホーン」を使用しており、複製する必要はありません。このタイプの1つの方法は、各自動車ブランドによって上書きされるべきであるが、特定のサブタイプの範囲内に留まるべきである。これは、すべての車のサブタイプのホーンのサブタイプを作成せずに可能ですか? ありがとうございました!JavaScriptでただ1つのインスタンスのオーバーライドメソッド

http://codepen.io/trek7/pen/QGYaBW

function Horn() { 
    this.level = '123dB'; 
} 

Horn.prototype.doTutut = function() { 
    return "Düdelüüüü!"; 
}; 

/********************************************/ 

function Car() { 
    this.horn = new Horn(); 
} 

Car.prototype.honk = function() { 
    return this.horn.doTutut(); 
}; 

/********************************************/ 

Mercedes.prototype = new Car(); 

function Mercedes() { 
    this.color = 'blue'; 
} 

Mercedes.prototype.drive = function() { 
    return "...BrumBrum..."; 
}; 

/********************************************/ 

Audi.prototype = new Car(); 

function Audi() { 
    this.color = 'red'; 

    /* BAD Overwrite, but how can I achieve this functionality 
    without creating another Horn subtype? */ 
    Horn.prototype.doTutut = function() { 
    return "Tütütütütü!"; 
    }; 
} 

Audi.prototype.honk = function() { 
    return this.horn.doTutut(); 
}; 

/********************************************/ 

var car = new Car();  
car.honk(); // Düdelüüüü! - Right! 

var mercedes = new Mercedes();  
mercedes.honk(); // Düdelüüüü! - Right! 

var audi = new Audi();  
audi.honk(); // Tütütütütü! - Right! 

mercedes.honk(); // Tütütütütü! - Wrong! 

答えて

1

ここでいつもの事はそれを作るために音を受け入れるようにHornクラスをパラメータに次のようになります。

function Horn(sound) { 
    this.sound = sound !== undefined ? sound : "Düdelüüüü!"; 
    this.level = '123dB'; 
} 

Horn.prototype.doTutut = function() { 
    return this.sound; 
}; 

その後Mercedes、たとえば、内、あなたは」 d Carスーパーコンストラクタにサウンドを渡すか、後でthis.hornに設定します。

function Mercedes() { 
    Car.call(this); // See below, important to do this first 
    this.horn.theMethod = function() { 
    // New implementation here 
    }; 
} 

を...それはあなたが最初に以下の継承のものを修正することが重要です:あなたは書き直す必要が全体の方法を持っている場合は


、あなただけthis.horn.theMethodに割り当てることができます。もちろん

、あなたが単一Hornインスタンスを共有するために(例えば)全てMercedesのインスタンスをしたい場合は、単にMercedes.prototype上の適切な方法でホーンを置きます。


サイドノート:あなたの継承設定では、繰り返し反復パターンが使用されています。これをしないでください。

Mercedes.prototype = new Car(); 

次の2つの問題がある、それを行う場合:

  1. Carの引数を受け入れ、

  2. Mercedes.prototype.constructorは間違っていることはできません

  3. Carオブジェクト(各サブクラス(MercedesAudiなど)のすべてのインスタンスは、同じオブジェクト(1つのホーン)を共有します。そのオブジェクトがステートレスである場合、それは素晴らしいですが、Car.prototypeにあったはずです。ステートレスでない場合は、Carインスタンス間の診断が難しいクロストークが発生します。

また、Mercedesは、Car、インスタンスのその部分を初期化する機会を与えるためにやっているべき、Carを呼び出すことはありません。ES5で

が、これはそれを行うための正しい方法です。もちろん

function Mercedes() { 
    // Gives `Car` its chance to do init; could pass on args here if appropriate 
    Car.call(this); 
    this.color = 'blue'; 
} 

// Set up the prototype chain  
Mercedes.prototype = Object.create(Car.prototype); 
Mercedes.prototype.constructor = Mercedes; 

Mercedes.prototype.drive = function() { 
    return "...BrumBrum..."; 
}; 

、ES2015にし、上記の(あなたがtranspilingで今使用できる)、それだけだ。

class Mercedes extends Car { 
    drive() { 
     return "...BrumBrum..."; 
    } 
} 

... コンストラクタがパラメータCarを受け入れない限り、使用する必要はありません。


ここで更新継承とサブクラスのすべてのインスタンス間で共有さホーンとの例を示します

// Horn with generic default 
 
function Horn(sound) { 
 
    this.sound = sound !== undefined ? sound : "Düdelüüüü!"; 
 
    this.level = '123dB'; 
 
} 
 

 
Horn.prototype.doTutut = function() { 
 
    return this.sound; 
 
}; 
 

 
// Car using a single generic horn across all Car instances 
 
function Car() { 
 
} 
 
Car.prototype.honk = function() { 
 
    return this.horn.doTutut(); 
 
}; 
 
Car.prototype.horn = new Horn(); 
 

 
// Mercedes with its own special horn 
 
function Mercedes() { 
 
    Car.call(this); 
 
} 
 
Mercedes.prototype = Object.create(Car.prototype); 
 
Mercedes.prototype.constructor = Mercedes; 
 
Mercedes.prototype.horn = new Horn("Mercedes Honk!"); 
 

 
// Audi with its own special horn 
 
function Audi() { 
 
    Car.call(this); 
 
} 
 
Audi.prototype = Object.create(Car.prototype); 
 
Audi.prototype.constructor = Audi; 
 
Audi.prototype.horn = new Horn("Audi Honk!"); 
 

 
// Usage 
 
var c = new Car(); 
 
console.log(c.honk()); 
 
var m = new Mercedes(); 
 
console.log(m.honk()); 
 
var a = new Audi(); 
 
console.log(a.honk());

+0

はい、右thatsの。私の(本当の)ケースでは音だけではなく、それは違う完全な方法です。 – trek7

+0

@ trek7: 'this.horn.theMethod'に新しい関数を割り当てることができます。私はその答えについてのメモを追加しました。 –

+0

@ trek7:ライブサンプルも追加されました。 –

関連する問題