2010-08-20 94 views
6

所以,這是我有一點點的最後嘮叨繼承問題,所以我想繼續前進,並問。所以,我會在PHP舉個例子:引擎蓋下的繼承

<?php 

class Base 
{ 
    private $z = 4; 


    function GetPrivate() 
    { 
     echo $this->z; 
    } 

} 

class Derived extends Base 
{ 
} 

$b = new Base(); 
$d = new Derived(); 

$d->GetPrivate(); 

>

夠簡單。當我一直閱讀有關繼承的內容時,解釋僅僅是「你繼承了公共和受保護的成員」,就是這樣。我沒有得到的是關於這個例子中的解釋者如何確定屬於什麼的一些事情。

例如,當創建派生類時,我可以使用Base的公共函數「GetPrivate」獲取基類的私有變量。然而,繼承的簡單定義不適用於我。我的意思是,我繼承了GetPrivate方法,但仍然有一些私有變量的鏈接,只是來自屬於基類的方法(即使$ this引用了派生類對象)。我無法在Derived類中創建一個新函數來訪問這些私有變量。

因此,解釋器是否保留了從基類繼承的功能以及它們對可用於該基類的私有成員的可能鏈接?

回答

2

解釋器(或其他OOP語言的編譯器),一次檢查訪問一步。

當你調用$d->GetPrivate();,解釋檢查的背景下,這是主要的(公共情境,因爲我認爲你是不是在相關類DrerivedBase)和GetPrivate()是一個公共方法。因此,在這種情況下允許$d->GetPrivate();,所以沒有錯誤。

GetPrivate(),上下文是$d對象作爲Base和訪問z是當前對象($d)的私人元件。因此訪問是有效的。

進入這裏的概念是'數據隱藏'(訪問控制)和'封裝'(數據和功能的組合)。

僅允許播放的繼承允許使用GetPrivate()Base,因爲它屬於Derived的對象。

的確,仍然存在私有數據的鏈接,但該鏈接不是直接鏈接。重要的是訪問發生爲Base類允許

因此,要回答你的問題是:

YES!解釋器會保留從基類繼承的函數以及它們對可用於該基類的私有成員的可能鏈接。

希望這會有所幫助。

2

答案是簡單的是,嘗試了這一點:

<?php 


class Base 
{ 
    private $z = 10; 

    public function getPrivate() 
    { 
     return $this->z; 
    } 
} 


class Derived extends Base 
{ 
    public function getPrivate() 
    { 
     return $this->z; 
    } 
} 

$a = new Derived(); 

echo $a->getPrivate(); 

你會看到,現在我們已經定義getPrivateDerived類,我們將不再能訪問zBase因爲它的私人,如果我們希望能夠從我們需要聲明它被保護而不是私有的派生類訪問它。

1

好了,我不能告訴太多關於解析器細節,但理解的關鍵是理解什麼visibility意味着:

類成員聲明爲public隨處訪問。聲明保護的成員只能在類本身以及繼承類和父類中訪問。聲明爲私有的成員只能由定義該成員的類訪問。

Now, the PHP manual also states

例如,當你擴展一個類,子類繼承所有的父類的公共和受保護的方法。除非一個類重寫這些方法,否則它們將保留它們的原始功能。

如果你在派生類中做了var_dump($d),你會看到它包含Base->z

object(Derived)#2 (1) { 
    ["z":"Base":private]=> 
    int(4) 
} 

因此,有在基本尺寸Z的參考,但它是私有的,因爲私有指會員只能由定義成員的類訪問,您無法從Derived訪問它。

通過在Base中提供公共方法以獲得私有成員,您可以通過父方法有效地控制訪問。也許$z是在擴展類中必須是隻讀的,例如數據庫適配器。

這是信息隱藏和訪問控制。這並不意味着,如果你擴展基地,你會失去$ z。繼承是一個is-a的關係。衍生is-a基地,因此它有一個$ z,雖然不是本身,但通過它的父母。