0

誰かが私に説明してもらえますか、なぜPHPで次のことを実行できるのですか?たとえば、C#またはJavaでは実行できません:

Class A {
    protected $a = 'Howdy!';
}

Class B extends A {
    public function howdy() {
        $created = new A();
        echo $created->a; <----- This is legal due to per-class visibility
    }
}

$b = new B();
echo $b->howdy();  <----- Hence, no fatal error here

この動作はここで指定されているようですが、この背後にある根本的な理由を理解できません (私の考えでは、明確な理由がなければ、per-class可視性の代わりに可視性を単純に実装することはできませんper-instance)。

4

5 に答える 5

2

これは、C# (さらに言えば Java) でも可能です。

class A                               // declare new class type B
{
   protected string a = "Howdy!";     // that has a protected member called `a`
}

class B : A                           // declare new type B which extends type A
{
   public void howdy()
   {
       A created = new A();
       Console.WriteLine(created.a);  // no problem accessing a b/c B extends A
   }
}


B bInst = new B();                    // create a new instance of type B
bInst.howdy();                        // invoke it's public method howdy()

基本的に何が起こっているかは次のとおりです。

  • クラス A には、呼び出された保護されたメンバーが含まれてaいます。これは、A を拡張するクラス (この場合はクラス B) のスコープで可視であることを意味します。
  • クラス B は a を拡張して、その保護されたメンバー (この場合はa)にアクセスできるようにします。
于 2012-05-18T14:01:30.800 に答える
2

あなたが指定したように、それが機能しない理由は、他の言語がインスタンスレベルのアプローチを使用するクラスレベルでアクセス制御を実装しているためです。

なぜ便利なのですか?クラスは、プライベート データを公開することなく、それ自体の他のインスタンスを操作できます。簡単な値オブジェクトの例を見てみましょう:

class Int {
    protected $value = 0;
    public function __construct($value) {
        $this->value = (int) $value;
    }
    public function add(Int $new) {
        return new Int($new->value + $this->value);
    }
}

$a = new Int(1);
$b = new Int(2);
$c = $a->add($b);

これにより、保護された情報をカプセル化したまま、複数のインスタンスで使用できます...

どちらのアプローチにも長所と短所があります...

于 2012-05-18T19:33:41.120 に答える
2

C# と Java の両方で行うことも可能です。protectedは、変数が A の任意のサブクラスからアクセスできることを意味します。B は A のサブクラスであるため、変数にアクセスできます。ここには魔法はありません。

于 2012-05-18T14:02:02.690 に答える
2

リンク先のページには、「他のオブジェクトからの可視性」というタイトルのセクションがあり、次のように述べています。

同じタイプのオブジェクトは、同じインスタンスではありませんが、お互いのプライベート メンバーと保護されたメンバーにアクセスできます。これは、実装固有の詳細が、これらのオブジェクトの内部ですでにわかっているためです。

于 2012-05-18T14:07:06.053 に答える
0

あなたがこれをした場合、それはうまくいきません:

$b = new B();
echo $b->a;

あなたの例では、B() から直接 $a メンバーにアクセスしていません。B() 内からインスタンス化された A() オブジェクトからアクセスしています。

于 2012-05-18T14:27:57.017 に答える