Home > まめ知識 > PHPのオーバーライドは仮想関数

PHPのオーバーライドは仮想関数

PHPでオーバーライドの挙動について調べてみました。

 もともとC++とかでプログラムしていたので、PHPの継承系の挙動について勉強していたところ、次のような疑問を感じました。

「継承元でクラス内別メソッドが使用している関数をオーバーライドするとどっちが呼ばれるのか?」

というわけで、実践・実践っと。


//継承元の実行
print "[継承元結果]";
$m_test = new test_base();
//継承後の実行
print "[継承後結果]";
$m_test = new test1();
exit;

class test_base{
	public function __construct(){
		if($this->printdata()){
			print "Printdata is true\n";
		}else{
			print "Printdata is false\n";
		}
	}

	protected function printdata(){
		return false;
	}
}

class test1 extends test_base{
	protected function printdata(){
		return true;
	}
}

継承元(test_base)のコンストラクタでprintdata関数を呼び出しています。このクラスを継承して、printfata関数をオーバーライドしたのが、test1クラスです。さて、実行するとどうなるのかな?

C++のvirtualで指定した関数みたいに動くならば、継承後はTrue、継承前は当然Falseになりそうです。

また、virtual指定してない関数みたいに動くならば、継承後も継承前もFalseになりそうです。

では、実行結果。

[継承元結果]Printdata is false
[継承後結果]Printdata is true

あ、virutual指定しているときの動作だ。そんな訳で、phpでは、オーバーライドは仮想関数扱いで動くみたいです。

$thisで指定されているものは、継承後は、継承後のメソッドを優先して使用し、オーバーライドメソッドがない場合は継承元の関数を呼ぶ。みたいな感じでしょうか。

 これはこれで困る場合もあるので、(勝手に継承元の挙動が変わったら困る挙動まで変わるおそれがある)ので、オーバーライドで継承元のメソッドが使用されるようにしたいときはどうすれば?と思ったのですが、そんな関数はそもそもオーバーライドさせないようにしてしまったらいいと思いました。

 うだうだ書いたのですが、上記のprintdata関数は、「挙動を変えられたくない」関数である場合は、宣言するときに

final protected function printdata()

みたいに宣言してしまえば、オーバーライドできなくなり、解決!みたいな感じです。

Comments:0

Comment Form

Trackbacks:0

Trackback URL for this entry
http://dev.tapweb.co.jp/2010/09/255/trackback
Listed below are links to weblogs that reference
PHPのオーバーライドは仮想関数 from tap dev blog

Home > まめ知識 > PHPのオーバーライドは仮想関数

Search
Feeds

Return to page top