- ベストアンサー
クラスの継承の仕方
後学のため、JavaScriptについて勉強しています。 JavaScriptでもクラス(のようなもの)を定義してオブジェクトを作成できるようですが、サブクラスを定義する方法が分かりません。メソッドやコンストラクタはどのように継承すればよいのでしょうか。 お分かりの方おられましたら、ご教授のほどお願い致します。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
JavaScriptにはクラス定義がないので、プロパティとメソッドを動的に継承しなければなりません。 プロパティは、コンストラクタから親のコンストラクタを呼び出すことで継承します。 ただし、その際 this のメソッドとして呼ばないと、親コンストラクタでの初期化が自分に反映されません。親コンストラクタをメソッドとして呼び出すには、 > call(または apply)メソッドを使い、「親コンストラクタ.call(this, 引数...)」とする。 または > 一時的に親のコンストラクタをプロパティに登録し、実行後に削除する。 という方法を取ります。 メソッドは、親の prototype を自分の prototype にコピーすることで継承します。 ただし、prototype はオブジェクトなので単に代入すると親のものを参照するようになってしまい、メソッドの追加などが親にも影響してしまいます。この問題の解法としては、 > for - in で prototype のプロパティを1つ1つコピーする。 とか > 親のインスタンスを作り、それを prototype に代入する。 というような方法が知られています。 しかし、for - in ではビルトインオブジェクトなどが持つ内部プロパティまでは取れないので、汎用的な継承の手段としては今ひとつです。 また、親のインスタンスを使う方法には余計な親コンストラクタ呼び出しが伴うので、親コンストラクタでクラスプロパティの変更などをしていると問題が生じます。 この問題を回避するには、親クラスと同じ prototype を持ち、コンストラクタでは何もしないダミークラスを定義して、そのインスタンスを prototype として使うようにします。 例:Base クラスを継承して Deriv クラスを構築する。 /**** class Base ****/ // コンストラクタ function Base(a) { ++Base.count; // 生成したBaseオブジェクトをカウント(親クラスを直接使って継承すると、問題が起こる例) this.a = a; } // メソッド定義 Base.prototype.print = function () { document.write("a=",this.a, "<br>"); } /**** class Deriv ****/ // コンストラクタ function Deriv(a, b) { // プロパティの継承 Base.call(this, a); // 固有プロパティの追加 this.b = b; } // メソッドの継承 function DerivPrototype() {} // 継承用ダミークラス DerivPrototype.prototype = Base.prototype; // プロトタイプは代入でOK Deriv.prototype = new DerivPrototype; Deriv.prototype.constructor = Deriv; // コンストラクタまで変更されてしまうので修正 // メソッド定義 Deriv.prototype.print = function () { // print のオーバーライド document.write("a=",this.a, ", b=",this.b, "<br>"); } このコードで気になるのは、メソッド継承の部分だけ抽象レベルが低いことでしょう。単に関数化するだけでも見通しは良くなりますが、次のように全ての関数の上位クラスである Function のメソッドとして登録すると、さらに可読性が高まります。 Function.prototype.inherit = function (baseClass) { function tempClass() {} tempClass.prototype = baseClass.prototype; this.prototype = new tempClass; this.prototype.constructor = this; } このコードをクラス定義の前に記述しておき、継承の部分は次のように変更します。 Deriv.inherit(Base); ※インデントなどに全角空白を使っているので、コピーする場合はタブなどに置換して下さい。
その他の回答 (2)
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
こんな感じ ------------------------------------------------------------- //Animalクラス //コンストラクタ function Animal(name, kind){ this.name=name; this.kind=kind; } //メソッド Animal.prototype.hey=function(){ return "I'm a " + this.name; }; Animal.prototype.toString=function(){ return "{" + this.name + " of " + this.kind +"}"; }; //Catクラス/Animalサブクラス function Cat(name){ this.name=name; this.kind="CAT"; } Cat.prototype=new Animal("","");//継承にあたる Cat.prototype.constructor=Cat;//コンストラクタは自分のを使う //新しいメソッド Cat.prototype.sing=function(){ return "nya-o"; };
お礼
ご回答ありがとうございます。 分かりやすいサンプルにより、JavaScriptでのクラスの理解が一層深まりました。 どうもありがとうございました。
- JeanneNet
- ベストアンサー率48% (100/208)
こんにちは、じゃんぬねっと です。 子Class.prototype = new 親Class; http://www.parkcity.ne.jp/~chaichan/src/javascnew04.htm
お礼
ご回答ありがとうございます。 提示して頂いたURLなど、大変参考になりました。 どうもありがとうございました。
お礼
ご回答ありがとうございます。 詳細な解説とサンプルのおかげで、問題点なども含めた非常に深い知識と、大変高度なテクニックを学ぶことができました。 どうもありがとうございました。