1

PHP で OOP の概念を修正しています。ここに、可視性を練習するための簡単な php コードがあります。

Big_Animal で $name を private として宣言すると、

1) クラスの外から $name に別の値を代入しようとしても (つまり、$lion->name="King")、エラーがスローされないのはなぜですか?

2) Lion クラスで $name を再割り当てしようとしたときにエラーがスローされないのはなぜですか (つまり、$this->name="John")。

私の知る限り、私は混乱しています.privateプロパティは、プロパティを定義するクラス内でのみアクセスできます。

私がはっきりしていない他のことは、保護されたプロパティです。私の理解では、保護されたプロパティは、クラス自体とその子クラス内でのみアクセスできます。孫クラスからアクセスできますか?

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

<?php
abstract class Big_Animal{

 private $name="Mary";

  abstract public function Greet();

 public function Describe(){
    return "name: ".$this->name;
}

public function __set($name,$value){
    $this->name=$value;
}

public function __get($name){
    return $this->name;
}
}

class Lion extends Big_Animal{


public function Greet(){
    $this->name="John"; //no error for this
    return " roar!";
}



public function Describe(){
        return parent::Describe()." I'm a Lion!";
    }
}


$lion = new Lion();
$lion->name="King";  //no error for this
echo $lion->Describe();
echo $lion->Greet();

?>
4

4 に答える 4

3
  1. マジックメソッドアクセサー(__setおよび__get)は、基本の抽象クラスでパブリックです。プロパティに直接アクセスしたときにプライベートデータに書き込むものです。魔法の方法をコメントアウトしてみてください。次に、出力は「名前:メアリー私はライオンです!咆哮!」です。

  2. これをLion::Describe()の最初のステートメントとして追加します。

    echo "ライオンの名前:"。$this->name。"\ n";

    ご覧のとおり、出力は「ライオンの名前:キング」になります。両方$this->name = "John"; および$lion->name = "King"; Lionクラスのオブジェクトのパブリックプロパティを変更しています。同じ名前のパブリックプロパティとプライベートプロパティの両方を持つことができるのは残念ですが、可能です。それらは単に異なる変数です(異なるスコープで)。

  3. 保護されたプロパティは、孫からアクセスできます。保護する本当に強い理由がない限り、ほとんどのプロパティを保護する必要があります(したがって、プライベートを使用します)。パブリックプロパティは、大規模なプロジェクトではあまり使用されません(スタイルによって異なります)。明示的なアクセサーを使い続けたいと思います。プロジェクトが進行し、より複雑になるにつれて、各変数にアクセサーを使用することを選択したことをうれしく思います。私はあなたのために足場アクセサーを生成するジェネレーターを使用することを好みます。これにより、多くの時間が節約され、エラーが削減され、アクセサーの作成がはるかに安価になります(したがって、より一般的になります)。

UPDATE(以下のコメントへの応答):1)および2)上記の2)でリストした両方のインスタンスでパブリック変数を編集しているため、エラーは発生しません。var_dump($ lion)を試してください:

object(Lion)#1 (2) {
  ["name":"Big_Animal":private]=>
  string(4) "Mary"
  ["name"]=>
  string(4) "John"
}

また、プライベートまたは保護されたメンバー変数を明示的にLionクラスに追加すると、予期したエラーが発生します。これはあまり直感的ではありませんが、PHPの現在の現実であるように思われることには同意します。

3)http://www.ibm.com/developerworks/opensource/library/os-php-7oohabits/には、プライベートメンバー変数のパブリックアクセサーを作成する例があります(ただし、ここでも、保護されたメンバーのパブリックアクセサーを作成することをお勧めします代わりに変数)。

于 2012-08-03T06:55:09.363 に答える
3

__set()のマジックメソッドを使っているため

__set() は、アクセスできないプロパティにデータを書き込むときに実行されます。

$lion->nameも使っているのでで値を取得することも可能__get()です。

于 2012-08-03T06:41:50.460 に答える
1

私のコメントを詳しく説明すると...__setという関数を使用しています。これが行うことは、このクラスの不明なプロパティに値を設定しようとするたびに、この特定の関数が呼び出されることです。

関数では、常にプライベート フィールド名を提供された値に変更しています。このクラスはそのフィールドにアクセスできるため、これが設定されます。

$lion->foo = "bar" と書いたとしても、関数 __set により、名前は bar に設定されます。

于 2012-08-03T06:46:24.783 に答える
-3

あなたの質問に対する答えはここにあると思います

定義上、抽象メソッドは派生クラスによって実装される必要があるため、抽象メソッドをプライベートにすることはできません。公開したくない場合は、保護する必要があります。つまり、派生クラスからは見えるが、それ以外は見えないということです。

于 2012-08-03T06:42:13.097 に答える