アプリ版:「スタンプのみでお礼する」機能のリリースについて

「クラス継承時のメンバ引継ぎの意味」と、
「privateでオーバーライドさせた際の挙動」ついて教えてください。

class Pa{
 private $level="10";

 public function getLevel(){
  return $this->level;
 }
}

class Ch extends Pa{
 protected $level="5";
}

$ch = new Ch();

echo $ch->getLevel();


このとき、$ch->getLevel();は、
Paクラスのメソッドをchオブジェクトで見に行ってるのでしょうか?
それとも、Chクラスに引き継がれたメソッドを見に行っているのでしょうか?

また、このときの「$this」「$this->level」は、それぞれ何を意味しているのでしょうか?

また、このときの、Chクラスの「$level」は、どういう状態(扱い)になっているのでしょうか?
エラーにならないのですが、再定義扱いされないのでしょうか?
新定義扱いされてるってことでしょうか?
「privateメンバを継承した際」、どういう動きをするのか(ルールになっているのか)教えてください。

A 回答 (3件)

その通りだと思います。

チマチマすれば
>Paクラスプロパティがprivateだったため、

>getLevel()があるPaクラスでは、プロパティがprivateだったため、
かな。

「$this」が何を示すかは柔軟に変化してしまうので、
・そのクラス内で宣言したプロパティを指したいのなら、継承先でも触れないprivate
・継承先で上書きされる可能性がある場合(許す場合)は、protected (または禁忌だけどpublic)で、という感じでしょうか。

(正式な解説ページ探したけど見つけられない…。以下がご参考になれば)
http://php.e1blue.net/term/entry.php?entryID=67& …
http://www.shigeweb.jp/php/project_p/?page=class …
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

大変勉強になりましたー!

お礼日時:2011/10/24 18:29

「2つ」は語弊があるので「2種類」に訂正。

pritate はそのクラスのスコープ専用なので、継承する各クラスに1つづつ、protected||public はオブジェクトに1つ。

この回答への補足

補足説明ありがとうございました。

1点確認させてください。
そうすると、echo $ch->getLevel();で返ってくる10というプロパティの所属先は、
Paクラスという認識であってるでしょうか?

つまり、この例の処理内容は、
chインスタンスオブジェクトを生成したのに、
Paクラスプロパティがprivateだったため、
chインスタンスオブジェクトのプロパティを取得出来ずに、
Paクラスに所属しているプロパティを取得した、という理解で合ってるでしょうか。

補足日時:2011/10/24 11:31
    • good
    • 0

同名のプロパティがある場合、そのクラスのprivateがまず優先されます。

(private という位なのでその値が保証されないと困ります。でないと結局継承先で上書きされてしまうことになる。)

>このとき、$ch->getLevel();は、~
流れで見ると
1.$ch = new Ch(); では、$ch->level は Chで宣言した 5
 (ただしPaクラス内に限り10)
2.$ch->getLevel(); でまず子クラスで関数を探す =>
3.存在しないので、親クラスのgetLevel()が実行される =>
4.親クラスでは $level は privateとprotected の2つがある =>
5.privateが優先されて、10 が返る
となるかと。

もしChの方にgetLevel()があれば、当然そこで宣言した 5 が返るでしょう。
また親クラスでの定義がなければ、優先すべきprivateは無いので 5が返ります。

>Chクラスの「$level」は、どういう状態~
privateと protected 2つのlevelがある状態。(var_dumpしてみて)

>新定義扱いされてるってことでしょうか?
と言ってもよいかと。後で宣言する方は最初の宣言よりゆるい場合のみ定義でき、またprotectedはpublicで上書きされるので、『事実上 同名のプロパティは privateと protectedまたはpublicの 「2つ」まで定義できる』ことになります。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

>2.$ch->getLevel(); でまず子クラスで関数を探す =>
>3.存在しないので、親クラスのgetLevel()が実行される =>
>5.privateが優先されて、10 が返る
詳しく説明いただいたので、大変分かりやすかったです。

お礼日時:2011/10/24 11:20

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!