2007年11月20日火曜日

JavaScript の継承

JavaScript と オブジェクト指向プログラミング (Object-Oriented Programming: OOP) に暫く焦点を当てていきます。

OOP 主要 3 原則

  • カプセル化
  • 継承
  • ポリモーフィズム

継承

OO デザインの特徴として、再利用があります。再利用の王道は継承です。
  • スーパークラスはサブクラスによって生成される
  • サブクラスはスーパークラスの全てのメソッドとプロパティを継承する
  • サブクラスでは継承したスーパークラスのメソッドやプロパティをオーバーライドできる
JavaScript では継承が公式にサポートされていませんが、継承を実装することはできます。
継承の方法を 2 通見てみます。

その 1: 関数による継承

サブクラスのオブジェクト定義の中で、スーパークラスのコンストラクタを呼ぶ方法です。
まず以下のようにスーパークラスとサブクラスを定義し、継承を確認します。
// スーパークラス
function superClass() {
this.bye = superBye;
this.hello = superHello;
}

function superHello() {
return "Hello from superClass";
}

function superBye() {
return "Bye from superClass";
}

// サブクラス
function subClass() {
// スーパークラスのコンストラクタを呼出し
this.inheritFrom = superClass;
this.inheritFrom();
this.bye = subBye;
}

function subBye() {
return "Bye from subClass";
}

// 継承を確認
var newClass = new subClass();

alert(newClass.bye());
///// "Bye from subClass"

alert(newClass.hello());
///// "Hello from superClass"
1 つ目の bye() メソッドはスーパークラスをオーバーライドした結果、subBye() が呼び出されています。
2 つ目の hello() メソッドは親クラスのメソッドを継承し superHello が呼出されています。

その 2: プロトタイプを使った継承

スーパークラスのオブジェクトを定義し、サブクラスのプロトタイプとする方法です。例 1 をプロトタイプを使った継承の方法で書き直すと以下のようになります。
 // スーパークラスのコンストラクタ
function superClass() {
this.bye = superBye;
this.hello = superHello;
}

function superHello() {
return "Hello from superClass";
}

function superBye() {
return "Bye from superClass";
}

function subClass() {
this.bye = subBye;
}

// サブクラスのプロトタイプとして
// スーパークラスのコンストラクタを呼出し
subClass.prototype = new superClass;

function subBye() {
return "Bye from subClass";
}

// 継承を確認する
var newClass = new subClass();

// サブクラスのプロパティが呼出される
alert(newClass.bye());
///// "Bye from subClass";

// サブクラスのプロトタイプ
// (= スーパークラスのコンストラクタ) から
// メソッドを呼出し
alert(newClass.hello());
///// "Hello from superClass";
コンストラクタが実行された後にスーパークラスのメソッドやプロパティを追加しても、サブクラスは新しいメソッドやプロパティを使うことができます。
この例として、以下のように、スーパークラスのプロトタイププロパティを加えてみます。
(上記の例の続きです。)
// スーパークラスのプロトタイプに新しいプロパティを追加
superClass.prototype.goodNight = superGoodNight();

function superGoodNight(){
return "Good Night from superClass.";
};

alert(newClass.goodNight);
///// "Good Night from superClass."
参考: Object-Oriented Programming with JavaScript, Part I: Inheritance

(続く)