PHP和C++一樣允許類的繼承,但存在一些自有的特性:
1. 僅允許繼承一個(gè)類,或者繼承多個(gè)接口;
2. 默認(rèn)類中的所有方法都具有C++中虛函數(shù)的特性,可以被子類重新覆蓋;除非使用final關(guān)鍵字,此時(shí)子類不可重新覆蓋該方法。

在類中通常使用$this->... 來(lái)訪問(wèn)類的屬性或者方法,此時(shí)$this實(shí)際上是實(shí)例化對(duì)象的映射,因此$this是不可能出現(xiàn)在靜態(tài)方法中的,這一點(diǎn)與C++很類似。除此之外,還能在類中使用self::... h和parent::... 來(lái)分別調(diào)用自身類方法和父類的方法,這些是PHP中特有的關(guān)鍵字。

接下來(lái)需要解答具體的問(wèn)題了。
1. 如何在子類中調(diào)用自身的方法?
答:使用$this->... 或者 self::... 來(lái)調(diào)用即可,但在靜態(tài)方法中只能使用self::... ,而且需要被調(diào)用方法中也沒(méi)有使用到$this關(guān)鍵字。
2. 如何在子類中調(diào)用父類的方法?
答:無(wú)論是子類未覆蓋的方法,直接使用$this->... 即可調(diào)用父類方法;如果是子類覆蓋了的方法,需要使用到parent::.. 來(lái)調(diào)用。
3. 如何在父類中調(diào)用子類的方法?
答:如之前所述,默認(rèn)類中所有方法都具有C++中虛函數(shù)的特性,因此如果父類中使用$this->... 調(diào)用某方法,無(wú)論該方法是否在父類中存在,而該方法被子類定義了,那么實(shí)際上調(diào)用的就是子類的方法。
具體見以下代碼:
class A {    
   
public function x() {        
      
echo "A::x() was called.\n";    
   }    
   
public function y() {        
      self
::x();        
      
echo "A::y() was called.\n";    
   }    
   
public function z() {        
      
$this->x();        
      
echo "A::z() was called.\n";    
   }
}
class B extends A {    
   
public function x() {        
      
echo "B::x() was called.\n";    
   }
}

$b = new B();
$b->y();
echo "--\n";
$b->z();

該例中,A::y()調(diào)用了A::x(),而B::x()覆蓋了A::x(),那么當(dāng)調(diào)用B::y()時(shí),B::y()應(yīng)該調(diào)用A::x()還是 B::x()呢?在C++中,如果A::x()未被定義為虛函數(shù),那么B::y()(也就是A::y())將調(diào)用A::x(),而如果A::x()使用 virtual關(guān)鍵字定義成虛函數(shù),那么B::y()將調(diào)用B::x()。
然而,在PHP5中,虛函數(shù)的功能是由 self 和 $this 關(guān)鍵字實(shí)現(xiàn)的。如果父類中A::y()中使用 self::x() 的方式調(diào)用了 A::x(),那么在子類中不論A::x()是否被覆蓋,A::y()調(diào)用的都是A::x();而如果父類中A::y()使用 $this->x() 的方式調(diào)用了 A::x(),那么如果在子類中A::x()被B::x()覆蓋,A::y()將會(huì)調(diào)用B::x()。

上例的運(yùn)行結(jié)果如下:

A::x() was called. A::y() was called.
--
B::x() was called. A::z() was called.