簡體   English   中英

PHP繼承,父函數使用子變量

[英]PHP inheritance, parent functions using child variables

在查看一些PHP代碼時,我發現了一件奇怪的事情。 以下是它的簡單示例說明:

文件A.php:

<?php
class A{
    public function methodA(){
        echo $this->B;
    }
}
?>

文件B.php:

<?php
    class B extends A{
        public $B = "It's working!";
    }
?>

文件test.php:

<?php
    require_once("A.php");
    require_once("B.php");
    $b = new B();
    $b->methodA();
?>

運行test.php打印出“它正在工作!”,但問題是它為什么有效? :)這是一個功能還是一個bug? 類A中的方法方法A也可以調用B類中不應該在OOP中工作的方法。

你只是在實例化B類。 暫時忽略A ,並假裝methodA()B類的一部分。

B類擴展A ,它獲得A的所有功能。 $this->B在代碼運行之前不會被評估,而不是之前。 因此不會發生錯誤,並且作為不會發生$this->B類存在B

PHP是一種動態語言。 方法和數據成員在運行時進行評估。 當您調用方法或訪問成員時,PHP實際上會查找排序的哈希表,以確定是否可以在此對象上訪問此方法或成員,這可以是繼承層次結構中的任何位置。

而且不僅僅是繼承,你總是可以在運行時將任意數據分配給一個對象,並且類中的代碼仍然可以使用$ this->某些東西來訪問它,其中“某些東西”甚至不存在於類中。

$this只是一個對象變量 - 一個特殊的變量,因為它是當前變量,但它仍然只是一個對象變量。

因為$B::B是一個公共成員變量,所以可以從任何地方訪問對B實例的引用,例如使用對象變量。

由於公共成員隨處可訪問,因此即使在A::methodA()也可以訪問任何函數。

所以實際上並不奇怪。 您的示例中的類繼承僅涉及在調用A::methodA()時以$this “參數”的形式傳遞對象變量的(不可見)。

請參閱以下示例,該示例可能使其更加明顯:

function methodA($object) {
    echo $object->B;
}

class B {
    public $B = "It's working!";
    public function methodA() {
        methodA($this);
    }
}

由於PHP是一種動態語言,因此調用正在使用它的實例上可能存在的屬性或方法沒有任何問題(在本例中是子類B的實例)

PHP是一種動態語言。 當在B的實例上調用methodA()時,B的成員$ B確實存在。

$a = new A();
$a->methodA();

不行。

在某些動態語言中,您甚至可以在運行時定義方法。

這對我有意義; 由於出現在B類中,$ B在結果對象中可用。因為$ this-> B在運行時被計算,並且在此之前設置了值(當B類被實例化時),它被發現是設置正確。

您也可以使用方法執行此操作,因為它們的存在在執行之前不會被檢查(盡管通常在方法的情況下在父類中聲明它們是抽象的,因此強制子項實現它們)。

這就是OOP的工作方式。 起初看起來有點奇怪,因為你認為A必須知道$this->B是第一個(實際上在某些語言中這會產生編譯器警告),但行為是正確的,因為子類你正在使用的是定義你的函數正在尋找的變量。 如果從A()的實例調用methodA() ,則會出現“未定義”錯誤。

現在,奇怪的是(讀: 錯誤 )如果有效:

class A {
   public $b = "Derp";
}
class B extends A {
  function sayIt() { echo $this->b; }
}
$a = new A();
$a->sayIt();

B類從A類擴展,因此它繼承了A類的方法methodA()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM