2009-12-27 61 views
6

我已經定義了一個抽象類和一個應該返回模板文件名稱的方法。用戶對這個抽象類進行子類化並實現該方法以返回模板文件名。但問題是,如果用戶沒有返回任何信息,則不會發出警告或任何事情。我可以強制抽象類的方法返回一些東西嗎?

我怎麼能確定這一點?調用此方法的代碼屬於框架,所以我可以用settype($returnVal, 'string')做一些奇特的事情,如果有幫助的話?有更好的解決方案嗎?

回答

11

在PHP中,你不能「強制」一個方法來返回任何東西 - 即使對於抽象類/方法和接口來說也是不可能的。

你能做的最好的是表明,實施中應返回的東西,使用評論 - 但你不能強迫人們這樣做:

/** 
* @param string $a blah blah 
* @return int The return value blah blah 
*/ 
public function my_method($a); 

當然,如果你調用這個方法(從框架的實施),您可以檢查已返回什麼,並拋出一個異常,如果它不符合你的預期是什麼?


這裏是如何這可能是一個簡單的例子實施:

class ClassA { 
    /** 
    * @param string $a blah blah 
    * @return ClassB The return value blah blah 
    */ 
    public function my_method($a) { 
     echo 'blah'; 
    } 
} 

class ClassB { 
    // ... 
} 


$a = new ClassA(); 
$returned = $a->my_method(10); 
if (!$returned instanceof ClassB) { 
    throw new Exception("Should have returned an instance of ClassB !"); 
} 

在這裏,由於該方法不返回ClassB的實例,所以會拋出異常。

+1

好,但它可以檢查返回值,對不對? – openfrog 2009-12-27 10:48:07

+1

@openfrog:是的,當然 - 但你必須自己編碼:它不是由PHP強制執行的(我在編輯你的評論時編輯了我的答案 - 我將再次編輯一個例子) – 2009-12-27 10:50:57

+0

這很棒。謝謝!!你實際上一次回答我的兩個問題:-) – openfrog 2009-12-27 10:55:05

1

據我所知,沒有辦法在PHP中實現返回值的類型提示。自PHP 5以來,function parameters的提示有限。

但即使有,你想要做的不是一個類型暗示的工作。如果我返回的字符串是空的,會發生什麼?無論調用哪個方法,您都需要檢查返回值,並做出適當的反應。

4

我能想到的唯一辦法做到這一點是建立在調用代碼將使用父類public final方法和protected方法將由public final方法被調用。 protected方法包含該功能,而public final方法驗證protected方法的返回值。

class A { 

    public final call_this($param) { 

     $return_value = $this->extend_this($param); 

     // validate $return_value 
     if($return_value == '') 
      throw new Exception("uh-oh! Don't return an empty string!"); 

     return $return_value; 

    } 

    protected extend_this($param) { 

     // default behavior 

     return $whatever; 

    } 

} 

class B extends A { 

    protected extend_this($param) { 

     // new behavior 

     return ''; //whoops! 

    } 

} 

$b = new B; 
$b->call_this("testing testing 123"); 
//exception! 

這可能是因爲雖然擴展類,如果你嘗試這樣的事情的人有點混亂,確保它是有據可查的。

public final是一種公共方法,如果您不知道,則不能被覆蓋。另外請注意,這隻能在PHP 5.0.0或更高版本中使用。

+0

不是真的,但它不回答關於抽象方法,因爲php7.1 – 2017-05-19 08:47:58

6

在PHP 7也能夠強制方法像這樣返回一個類的實例:

class MyClass 
{ 
    public function getData(): MyData 
    { 
     return 1234; //TypeError! 
    } 
} 
class MyData 
{ 
} 

以這種方式,下面的代碼是無效的,並拋出一個TypeError

$obj = new MyClass(); 
$obj->getData(); 

Sandbox

+2

這也可以在抽象方法中完成:abstract public function getData():MyData; – 2017-05-19 08:47:22

相關問題