2019/2/6 php privateメソッド、privateプロパティとオーバーライド・継承

オーバーライド時のアクセス修飾子変更 PHP 編

<?php

class RRR{
	public $prop='rrr';
	public function meth(){
		echo $this->prop;
	}
	
	public function call(){
		$this->meth();
	}

}


class SSSS extends RRR{
	public $prop='sssss';
	public function meth(){
		echo 'override!!!!!!';
	}
/*
*	public function call(){
*		$this->meth();
*	}
*/
}

$ins_S=new SSSS;

$ins_S->call();
//override!!!!!!

②RRRクラスとSSSSクラスのmethメソッドをprivateにしてみる。


<?php

class RRR{
	public $prop='rrr';
	private function meth(){
		echo $this->prop;
	}
	
	public function call(){
		$this->meth();
	}

}


class SSSS extends RRR{
	public $prop='sssss';
	private function meth(){
		echo 'override!!';
	}
/*
*	public function call(){
*		$this->meth();
*	}
*/
}

$ins_S=new SSSS;

$ins_S->call();
//sssss

SSSSクラスにcallメソッドは定義してないのでスーパークラスであるRRRクラスのcallメソッドが呼ばれる。

callメソッド中の$thisは$ins_Sを指すのでSSSSクラスのmethメソッドを呼ぼうとする。しかしSSSSクラスのmethメソッドはprivateメソッドなのでRRRクラス内のcallメソッド内からは呼べない。なのでSSSSクラスのスーパークラスであるRRRクラスのmethメソッドが呼ばれる。

RRRクラスのmethメソッド内の$thisは$ins_Sを指すのでそのpropプロパティの値である’sssss’が表示されていると思われる。


③RRRクラスとSSSSクラスのpropプロパティもprivateにしてみる。


<?php

class RRR{
	private $prop='rrr';
	private function meth(){
		echo $this->prop;
	}
	
	public function call(){
		$this->meth();
	}

}


class SSSS extends RRR{
	private $prop='sssss';
	private function meth(){
		echo 'override!!';
	}
/*
*	public function call(){
*		$this->meth();
*	}
*/
}

$ins_S=new SSSS;

$ins_S->call();
//rrr

RRRクラスのmethメソッドが呼ばれるまでは②と同じ。$ins_Sのpropプロパティにアクセスしようとするが、SSSSクラスの$propプロパティはprivateなのでRRRクラス内のmethメソッド内からアクセスできない。なのでSSSSクラスのスーパークラスであるRRRクラスのpropプロパティにアクセス。その値’rrr’が表示されていると思われる。


④親クラスのプロパティ・メソッドはprivate、子クラスのプロパティ・メソッドはpublic


<?php

class RRR{
	private $prop='rrrwwww';
	private function meth(){
		echo $this->prop;
	}
	
	public function call(){
		$this->meth();
	}

}


class SSSS extends RRR{
	public $prop='sssss';
	public function meth(){
		echo 'override!!!!!!';
	}
/*
*	public function call(){
*		$this->meth();
*	}
*/
}

$ins_S=new SSSS;

$ins_S->call();
//rrrwwww

ここがひっかかていたところだが、この結果で間違いないと思われる。もともと②で打ち消した部分のような認識だった。ただそれだと今回(④)はサブクラスのmethメソッドはpublicなのでアクセスできる、よって

‘override!!!!!!’

が表示されるはず。しかし実際は違う。

「オーバーライドする側(子クラス側)がprivateメソッドだから呼び出せない」のではなく、

「オーバーライドされる側(親クラス)がprivateメソッドの場合、オーバーライドできない」ということか。


⑤親クラスのmethメソッドをprotectedにしてみる。


<?php

class RRR{
	private $prop='rrrwwww';
	protected function meth(){
		echo $this->prop;
	}
	
	public function call(){
		$this->meth();
	}

}


class SSSS extends RRR{
	public $prop='sssss';
	public function meth(){
		echo 'override!!!!!!';
	}
/*
*	public function call(){
*		$this->meth();
*	}
*/
}

$ins_S=new SSSS;

$ins_S->call();
//override!!!!!!

この場合もオーバーライドできている、ということか。

 

コメントを残す

メールアドレスが公開されることはありません。