2013-04-28 11 views
6

私はOOPSでチェスプログラムを書いて、私はなぜJavascriptはデフォルトで継承をサポートしていないのですか?

Class Piece{ 
    int teamColor; 
    bool isLive; 
    Positon pos; 
    int Points; 
    ....... 
    int getTeamColor(){....} 
    ....... 
}; 

Class Rook extend Piece{ //`is-a` 
...... // No getTeamColor() definition here.. because the parent has the definition. 
}; 

Class Pawn extend Piece{ //`is-a` 
......// No getTeamColor() definition here.. because the parent has the definition. 
}; 

、としてis-a関係を実装する場合ならばベースOOPSからのように、私はいつも私は、

例、コードの再利用のための強力なツールとして継承を使用has-aの関係でこれを行うことができますが、私が見ている欠点は です。派生クラスのすべての関数も再定義する必要があります。

例:など、すべてのルーク、騎士、質屋、王で再びgetTeamColorの再定義().... ..

 var Pawn = function(teamColor,pos){ 
    var piece = new Piece(teamColor,pos); 
    ....... 

    this.getTeamColor = function(){   
      return piece.getTeamColor(); 
    }; 
    } 

私の質問は、なぜjavascriptのdoesnotデフォルトのオプションとして、古典的な継承をサポートし、 です?

+0

jOOPL(http://joopl.codeplex.com)をご覧ください。これは、クラスベースのOOPをサポートするための言語を強化する100%JavaScriptオブジェクト指向ライブラリです。したがって、継承と多型(さらに多くの機能)があります。私は数日間で新しいバージョンをリリースしようとしています。 –

+6

JavaScriptは継承*をサポートしています。 "JavaScriptプロトタイプチェーン"を参照してください。 "なぜjavascriptが古典的な継承をデフォルトオプションとしてサポートしていないのか?" JavaScriptが定義されているからです。なぜJavaはTraitsを持っていませんがScalaはどうしますか?なぜRubyはPythonでMIをサポートしていますか?なぜC++にはDylanのMultiple Dispatchがありませんか?なぜエッフェルはLSPの中断を許していますか?まあ、彼らは*別の言語*であり、一方が正しいと主張する - 間接的な "古典的"手段 - は、別のアプローチがそれ以上(またはそれ以上)有効であることを否定することです。 – user2246674

+0

javascriptオブジェクトモデルの詳細については、Mozilla Developer Networkの全記事を参照してください。 [ここにリンク](https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Details_of_the_Object_Model)。この記事では、Java(クラスベース)とJavascript(プロトタイプベース)を比較する際の継承、階層、および関係について説明します。 –

答えて

13

をJavaScriptが原型途中で継承をサポートしています。ここで必要なのはクラスではなく、動作のカプセル化と上書きする能力です。

function Piece() { } 

Piece.prototype.color = "white"; 
Piece.prototype.getColor = function() { return this.color } 
Piece.prototype.move = function() { throw "pure function" }; 

function Pawn() { } 
Pawn.prototype = new Piece();  
Pawn.prototype.move = function() { alert("moved"); } 

となりました:

var p = new Pawn(); p.color = "black"; 

> p instanceof Piece 

p instanceof Pawn 

p.getColor() 

"黒"

p.move() 

アラートが...

これは基本的なアプローチであるとクラスを望む男性のためのよく知られているものに、これを有効にそこに多くのライブラリがある - そう言いました。次のコードブロックから1つのJavaScriptのプロトタイプを「拡張」します

var Piece = $data.Base.extend("Piece", { 
    move: function() { throw "pure class" } 
}); 

var Pawn = Piece.extend("Pawn", { 
    move: function() { ... } 
}); 

var p = new Pawn(); 
7

JavaScriptはclass-based object-oriented languageではなく、むしろprototypalです。それは単に設計上の決定です。

また、Javascriptは今日(Node.jsからASM.jsまで)私たちがやっているすべてのことに対して決して実際には意味がありませんでした。それがまだ関連しているという事実はBrendan Eich and Co.の証です。なぜXやYがJSで実装されたのか疑問に思うかもしれませんが、事実はJSを20年前に予期せぬものに使うことです。

1

さまざまな伝統的なOO言語(Java、C#、C++など)に関する多くの優れた書籍は、可能であれば「実装継承」を使用することを特に勧めています。例:Joshua Blochの効果的なJava

奇妙な事実は、実装の継承はコードに規則的な「シェイプ」を与えているようですが、実際に問題を解決するのには役立っていないことです。それは長期的には問題を引き起こします。

これらの著者は、 "継承を継承する"代わりに彼らの祝福を与える傾向がありますが、JavaScriptなどのダック型言語では、そのような継承を明示的に宣言する必要はありません。

JSでは、同じ機能を複数のオブジェクトのプロパティとして割り当てるだけで、同じ機能を「再利用」することができます。あなたが必要とする相続財産が何であれ、あなたはそれを何のものからも引き立てることができます。

1

JavaScriptには実際のOOPスタイルのクラスさえありません。同様のものをシミュレートするだけです。

あなたの例では、あなたが

var Pawn = function(teamColor, pos) { 
    Piece.call(this, teamColor, pos); 
} 

を行うことで、継承を実現することができますただし、関数のプロトタイプにではなく、すべての新規作成されたオブジェクトにメソッドを通常添付しなければなりません。 CoffeeScriptのは、それをしないようにその場合、あなたは、例えば、プロトタイプチェーンを設定することで、継承をシミュレートすることができます。

var a, b, _ref, 
    __hasProp = {}.hasOwnProperty, 
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; 

a = (function() { 
    function a() {} 

    return a; 

})(); 

b = (function(_super) { 
    __extends(b, _super); 

    function b() { 
    _ref = b.__super__.constructor.apply(this, arguments); 
    return _ref; 
    } 

    return b; 

})(a); 
+4

これは、必要なタスクのためのimhoの過剰な(そして少しばかげた)ものです。 –

0

:あなたが連鎖アップ自動コンストラクタ呼び出しのボーナスで、よりカプセル化の方法(で前回を書くことができますJayDataで例えば

その他、および「instanceofの」オペレータは、ベースと派生クラスのために正常に動作することを確認してください。私は、「instanceofの」オペレータの論理的、一貫性を保つために可能にする新しい種皮にTESTBのプロトタイプを設定し、伝えることができるものから、

を。

これをTestAに渡すと、新しいインスタンスに必要なプロパティとメソッドがすべて与えられます。

このようにすることは、文体的な欲望と実践的なものとのバランスの一種です。これはほとんどのブラウザで動作します。たとえサポートが必要な場合でもInternet Explorerですら動作します。また、同じブロックに含まれているメソッドを従来のOO構文のように「感じる」ようにするために役立ちます。

また、JavaScriptがOOの伝統的なスタイルをサポートしていない主要な理由は、創業思想のためです。創業の哲学は自由です。この自由は、開発者がプロ​​ジェクトのニーズに合わせて独自のスタイルを設計できるようにすることを目的としています。

function TestA(){ 
    var me = this; 

    me.method = function(){ 
    } 
} 

function TestB(){ 
    TestA.call(this); 
    var me = this; 

    me.otherMethod = function(){ 
    } 
} 
TestB.prototype = new TestA(); 

var test = new TestB(); 

console.log(test); 

console.log(test instanceof TestB); 
console.log(test instanceof TestA); 

//TestA { method: [Function], otherMethod: [Function] } 
//true 
//true