2016-10-02 243 views
2

我只是寫這樣的代碼:抽象類方法聲明

<?php 
class test 
{ 
// Force Extending class to define this method 
abstract protected function getValue(); 
abstract protected function prefixValue($prefix); 

// Common method 
public function printOut() { 
    print $this->getValue() . "\n"; 
} 
} 
class testabs extends test{ 

public function getValue() 
{ 

} 
public function prefixValue($f) 
{ 

} 
} 
$obj = new testabs(); 
?> 

當我運行這段代碼,我收到以下錯誤:

Fatal error: Class test contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods (test::getValue, test::prefixValue) in C:\wamp64\www\study\abstract.php on line 12

我明白了這個錯誤的第一部分。我將課堂測試改爲抽象,錯誤消失了,但or部分我無法理解。

+0

這個_or_部分是從一個類擴展你的'test'類的角度來看的。它是雙向的;或者讓你的'test'類抽象或者讓任何其他類擴展'test'抽象,因爲它們沒有實現任何繼承的抽象聲明。 – dbf

回答

4

如果您要添加抽象方法,那麼您還需要創建類abstract。這樣,該類不能實例化 - 只有非抽象的子類纔可以。

visibility(參見第二小節Method Visiblilty)在子​​類中是不相同的。根據您是否希望通過子類外的代碼調用方法,您可以創建類testpublic中的(抽象)方法,或者也可以使子類方法也爲protected

並注意從Class Abstraction page第二段,這也解釋了這一點:

When inheriting from an abstract class, all methods marked abstract in the parent's class declaration must be defined by the child; additionally, these methods must be defined with the same (or a less restricted) visibility. For example, if the abstract method is defined as protected, the function implementation must be defined as either protected or public, but not private

<?php 
abstract class test{ 
    // Force Extending class to define this method 
    abstract protected function getValue(); 
    abstract protected function prefixValue($prefix); 

    // Common method 
    public function printOut() { 
     print $this->getValue() . "\n"; 
    } 
} 
class testabs extends test{ 

    protected function getValue() 
    { 

    } 
    /** 
    * this method can be called from other methods with this class 
    * or sub-classes, but not called directly by code outside of this  class 
    **/ 
    protected function prefixValue($f) 
    { 

    } 
} 
$obj = new testabs(); 
// this method cannot be called here because its visibility is protected 
$obj->prefixValues();// Fatal Error 
?> 
+0

當我創建對象我得到了錯誤 –

+0

好吧,我更新了我的答案 - 看到新的第一段。 –

1

你的類有抽象的功能,但不聲明爲抽象的,所以你有兩個選擇。要麼將該類聲明爲abstract,要麼提供抽象函數的實現。

第一個選項(您嘗試過)允許類存在並由具體子類實現函數使用。第二個選項意味着該類是完全定義的,可以按原樣使用。

0

當你的classabstract方法它也必須宣佈abstract也。 所以下面是正確的:

<?php 
abstract class test 
{ 
    // Force Extending class to define this method 
    abstract protected function getValue(); 
    abstract protected function prefixValue($prefix); 

    // Common method 
    public function printOut() { 
    print $this->getValue() . "\n"; 
    } 
} 
0

關鍵的抽象類接口之間的技術區別是:

  • 抽象類可以有常量,成員,方法存根(法無一個主體)和定義的方法,而接口只能有常量和方法存根。
  • 抽象類的方法和成員可以用任何可見性來定義,而接口的所有方法都必須定義爲public(它們是默認定義的)。
  • 當繼承抽象類時,具體的子類必須定義抽象方法,而抽象類可以擴展另一個抽象類,而不必定義父類的抽象方法。
  • 類似地,擴展另一個接口的接口不負責從父接口實現方法。這是因爲接口不能定義任何實現。
  • 子類只能擴展單個類(抽象或具體),而接口可以擴展或類可以實現多個其他接口。
  • 子類可以定義具有相同或更少限制性可見性的抽象方法,而實現接口的類必須定義具有完全相同可見性(public)的方法。
相關問題