- ベストアンサー
PHPでサブクラスからスーパクラスのprivateメンバにアクセスできる件について
- PHPのサブクラスからスーパークラスのprivateなメンバにアクセスできることについて質問です。
- サブクラスのインスタンスから継承したpublicなメソッドを実行すると、スーパークラスのprivateなプロパティにアクセスできてしまう現象が発生します。
- 通常、privateメンバはそのクラスの中からしかアクセスできませんが、この場合はどういうことかご教示ください。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
#1です >$obj = new ExClass(); >$obj-> testMethod01(); >ここから見える(アクセスできる)かどうかです。 というのは、スーパ-クラスを継承したExClassというサブクラスから継承元までさかのぼってという意味でしょうか? そこはひとまず置いて考えてみると分かりやすくなると思います。 サブクラスからアクセスできるのはtestMethod1とtestMethod2です。 ここまではたぶん理解されていると思います。 ではtestMethod1(もしくはtestMethod2)から見える範囲は? →TestClass内の各メソッドやプロパティです。 単純にこれだけの話です。なので・・・ 以下メソッドは、スーパークラスで定義してサブクラスに継承されたクラスですよね。 public function testMethod01 () { print "スーパークラスのパブリックメソッド"; print "<h1>{$this->value01}</h1>"; } >$obj-> testMethod01(); 上の継承したメソッドtestMethod01()を実行している時点でExClassのインスタンスだけど 実際はスーパ-クラス内に入りこんでTestClass(スーパクラス)として振る舞っているということでしょうか? 「入り込んで」の解釈の仕方が適切なのかはわかりませんが、そういう理解の仕方でもよいと思います。 (ちょっと適当) また、このtestMethod01というメソッドと全く同じ内容でサブクラスでオーバーライドした場合は上記とは異なる動きになりますよね? オーバ-ロードした場合、サブクラス内で【$this->value01】というプロパティを探す動きにかわるとおもいますが、 オーバ-ロードした場合は完全に、サブクラスとして振る舞うというような解釈でしょうか? これはサブクラス内にtestMethod01を定義(オーバーライド)しているという意味ですかね? こんな意味で間違ってなければ・・・ class ExClass extends TestClass{ private $value01 = "サブクラスの private メンバ"; public function testMethod01 () { print "ここに表示されるのは?"; print "<h1>{$this->value01}</h1>"; } } ここでの$this->vakue01はサブクラスの値です。 なぜなら$thisはサブクラスなので。 ってここまで書いて気づきましたがオーバーロードですか?オーバーライドですか? PHPでオーバーロードって最近はあまり聞きませんが、意味合いが異なってきますのでちょっと悩ましいです。 これはJavaチックな考え方ですかね?あんま詳しくないのでよくわかりませんが・・・ http://php.net/manual/ja/language.oop5.overloading.php
その他の回答 (1)
- 1minn
- ベストアンサー率57% (52/90)
えーとそういう事です・・・ あくまで$obj->testMethod01() はpublicメソッドへのアクセスなので問題はないです。 クラスの外側 $obj = new ExClass(); $obj-> testMethod01(); ここから見える(アクセスできる)かどうかです。 testMethod01からは「同じクラス内」のメンバ変数にアクセスできるので、そのような状態になります。 testMethod01がgetterだと思えば分かりやすいかと。 (より混乱されるようでしたらこれは忘れてください)
補足
え-と >$obj = new ExClass(); >$obj-> testMethod01(); >ここから見える(アクセスできる)かどうかです。 というのは、スーパ-クラスを継承したExClassというサブクラスから継承元までさかのぼってという意味でしょうか? 以下メソッドは、スーパークラスで定義してサブクラスに継承されたクラスですよね。 クラス定義自体は省略します。 public function testMethod01 () { print "スーパークラスのパブリックメソッド"; print "<h1>{$this->value01}</h1>"; } >$obj-> testMethod01(); 上の継承したメソッドtestMethod01()を実行している時点でExClassのインスタンスだけど 実際はスーパ-クラス内に入りこんでTestClass(スーパクラス)として振る舞っているということでしょうか? また、このtestMethod01というメソッドと全く同じ内容でサブクラスでオーバーライドした場合は上記とは異なる動きになりますよね? オーバ-ロードした場合、サブクラス内で【$this->value01】というプロパティを探す動きにかわるとおもいますが、 オーバ-ロードした場合は完全に、サブクラスとして振る舞うというような解釈でしょうか?
お礼
ありがとうございます。 なんとかつかめた気がします。 オーバーロードに関しては入力間違いです。ごめんなさい。 class SuperClass{ public $publicValue = "スーパークラスのパブリックプロパティ"; protected $protectedValue = "スーパークラスのプロテクティッドプロパティ"; private $privateValue = "スーパークラスのプライベートプロパティ"; public function superPublicMethod(){ print "どこからでも見えるメソッド"; } protected function superProtectedMethod(){ print "親及び子クラスのクラス定義の中のみ参照可"; } private function superPrivateMethod(){ } public function superGetMethodList(){ var_dump(get_class_methods($this)); var_dump(get_class_vars(get_class($this))); } } class SubClass extends SuperClass{ public $publicValue = "サブクラスのパブリックプロパティ"; protected $protectedValue = "サブクラスのプロテクティッドプロパティ"; private $privateValue = "サブクラスのプライベートプロパティ"; public function subGetMethodList(){ var_dump(get_class_methods($this)); var_dump(get_class_vars(get_class($this))); } } $obj = new SubClass(); //クラス定義の外側なので private protected メソッドは不可視である。 var_dump(get_class_methods($obj)); var_dump(get_class_vars(get_class($obj))); $obj -> subGetMethodList(); $obj -> superGetMethodList(); ------------------------------------------------------------------------------------------------ array 0 => string 'subGetMethodList' (length=16) 1 => string 'superPublicMethod' (length=17) 2 => string 'superGetMethodList' (length=18) array 'publicValue' => string 'サブクラスのパブリックプロパティ' (length=48) ------------------------------------------------------------------------------------------------ array 0 => string 'subGetMethodList' (length=16) 1 => string 'superPublicMethod' (length=17) 2 => string 'superProtectedMethod' (length=20) 3 => string 'superGetMethodList' (length=18) array 'publicValue' => string 'サブクラスのパブリックプロパティ' (length=48) 'protectedValue' => string 'サブクラスのプロテクティッドプロパティ' (length=57) 'privateValue' => string 'スーパークラスのプライベートプロパティ' (length=57) ------------------------------------------------------------------------------------------------ array 0 => string 'subGetMethodList' (length=16) 1 => string 'superPublicMethod' (length=17) 2 => string 'superProtectedMethod' (length=20) 3 => string 'superPrivateMethod' (length=18) 4 => string 'superGetMethodList' (length=18) array 'publicValue' => string 'サブクラスのパブリックプロパティ' (length=48) 'protectedValue' => string 'サブクラスのプロテクティッドプロパティ' (length=57) 'privateValue' => string 'スーパークラスのプライベートプロパティ' (length=57) ------------------------------------------------------------------------------------------------ と上記のようなコードを描いてしらべたところなんとか把握できました。 どうやらあちこちのサイトで描かれているサブクラスはスーパークラスのpublicおよびprotectedのメンバが継承されるという 記述を数多くみてきたせいで、サブクラスにはスーパークラスのprivateはいっさい継承されないものとおもっていました。 だから、サブクラスからスーパークラスのprivateなメンバにアクセスできるのが謎だったんですね。これはマニュアルもちょっと記述の仕方を考えてほしいなとおもったところです。