2013年3月25日月曜日

PHP 継承とオーバーライド

継承

クラスを継承するにはextendsキーワードを使用します。
多重継承はできません。
構文
class 子クラス extends 親クラス {
}


インスタンスメンバをオーバーライド

子クラスでメソッドをオーバーライドしなかった場合、親クラスのメソッドが呼び出されます。
子クラスから親クラスのメンバにアクセスするには「parent::」を利用します。

コンストラクタもメソッドと同じで、
子クラスでコンストラクタを定義しない場合は、親クラスのコンストラクタが継承されます。
子クラスでコンストラクタを定義した場合は親クラスのコンストラクタは自動で呼び出されませんので、親クラスのコンストラクタを明示的に呼び出す必要があります。
親クラスのコンストラクタを呼ばなくてもエラーにはなりません。
<?php
//親クラス
class ParentClass {
    protected $instanceField = 0;
    
    public function __construct($instanceField) {
        print('ParentClass:Construct</br>');
        $this->instanceField = $instanceField;
    }
    
    public function showInstanceField() {
        print($this->instanceField .'</br>');
    }
}
//子クラス1
//親クラスのメソッド、コンストラクタをオーバーライドしない。
class ChildClass1 extends ParentClass {
}

//子クラス2
//親クラスのメソッド、コンストラクタをオーバーライドする。
class ChildClass2 extends ParentClass {
    public function __construct() {
        print('ChildClass2:Construct</br>');
        $this->instanceField = 2;
    }
    
    public function showInstanceField() {
        print('ChildClass2:showInstanceField</br>');
        print($this->instanceField .'</br>');
    }
}
//子クラス3
//親クラスのメソッド、コンストラクタをオーバーライドし、親クラスのメソッドを利用する。
class ChildClass3 extends ParentClass {
    public function __construct() {
        print('ChildClass3:Construct</br>');
        parent::__construct(3);
    }
    
    public function showInstanceField() {
        print('ChildClass3:showInstanceField</br>');
        parent::showInstanceField();
    }
}


//使用例
print('-----子クラス1-----</br>');
$child1 = new ChildClass1(1);
$child1->showInstanceField();

print('-----子クラス2-----</br>');
$child2 = new ChildClass2();
$child2->showInstanceField();

print('-----子クラス3-----</br>');
$child3 = new ChildClass3();
$child3->showInstanceField();
?>
実行結果



スタティックメンバのオーバーロード

スタティックなメンバもインスタンスメンバと同じく、
子クラスでメソッドをオーバーライドしなかった場合、親クラスのメソッドが呼び出されます。
子クラスから親クラスのスタティックメンバにアクセスするには「parent::」を利用します。
子クラスで親クラスのメンバをオーバーライドしなかった場合は「self::」を利用することもできます。
<?php
//親クラス
class ParentClass {
 protected static $staticField = 5;
 
 public function __construct() {
  print('ParentClass:Construct</br>');
 }
 
 public static function showStaticField() {
  print(self::$staticField .'</br>');
 }
}
//子クラス1
//親クラスのスタティックメソッドをオーバーライドしない。
class ChildClass1 extends ParentClass { 
}

//子クラス2
//親クラスのスタティックメソッドをオーバーライド
//スタティック変数はオーバーライドしていないので「parent::」でも「self::」でアクセス可能。
class ChildClass2 extends ParentClass {
 public static function showStaticField() {
  print('ChildClass2:showStaticField' .'</br>');
  print(self::$staticField .'</br>');
 }
}
//子クラス3
//親クラスのスタティック変数、スタティックメソッドをオーバーライド
//「parent::」では親クラスのスタティック変数を参照し、「self::」では自クラスのスタティック変数を参照する。
class ChildClass3 extends ParentClass {
 protected static $staticField = 3;
 
 public static function showStaticField() {
     print('ChildClass3:showStaticField' .'</br>');
  print(self::$staticField .'</br>');
  print(parent::$staticField .'</br>');
 }
}


//使用例
print('-----子クラス1-----</br>');
ChildClass1::showStaticField();

print('-----子クラス2-----</br>');
ChildClass2::showStaticField();

print('-----子クラス3-----</br>');
ChildClass3::showStaticField();

?>
実行結果

0 件のコメント: