web-dev-qa-db-ja.com

PHP変数のオーバーライド

PHPのクラスメソッドをオーバーライドするのと同じ方法でクラス変数をオーバーライドしようとすると。お気に入り:

class DataMapper {
     protected $_name = null;

     public function printName() {
          echo $this->_name;
     }
}

class Model extends DataMapper {
     protected $_name = 'Ana';
}

$test = new Model();
$test->printName();

プリント「アナ」です。

なぜPHPはそのようなことをすることができるのですか?それはオブジェクト指向パラダイムの法則を破ります

21
brian

そうではありません。これがPHPが機能するはずです。 PHPクラスとオブジェクトの可視性 を見てください。

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

ModelはDataMapperを拡張するため、関数や変数などにアクセスできますが、それらをオーバーライドすることができます。関数はDataMapperクラスにありますが、名前がAnaに設定されているModelクラスから呼び出されます(継承されます)。

25

$ thisが何をするのか理解するのに苦労しているだけだと思います。 $ thisを参照すると、実際には現在のオブジェクトを参照しています。

DataMapperクラスを継承すると、printName()メソッドはModelオブジェクト内でアクセス可能になりますが、$ this参照は、現在のModelオブジェクトである$ testを参照します。

Modelオブジェクトの$ _nameプロパティは「Ana」にインスタンス化されているため、Anaを出力しています。これはまさに期待されていることです。おそらく、継承とスコープの理論をもう一度読んでおくと、ここで何が起こっているのかを理解するのに役立ちます。

4
BraedenP

これが「OOの法則」に違反するとは思わない。 DataMapperクラスを継承しました。したがって、パブリック関数printName()を継承しました。したがって、関数を呼び出すと、モデルクラスに属する関数のように機能します。

3
Balanivash