2016-11-09 139 views
3

我目前有一個抽象類,我正在擴展到其他控制器。我在抽象類中有一個抽象函數,它取值並將其放在__construct中。可選的抽象方法

abstract class Controller extends BaseController { 
    abstract public function something(); 

    public function __construct(Request $request) { 
     if (!is_null($this->something())){ 
      $this->global_constructor_usse = $this->something(); 
     } 
    } 
} 

我的問題是,在不需要此抽象函數的控制器上,我不得不放置在空函數中。

class ControllerExample extends Controller { 
    public function something(){ 
     return 'somethinghere'; 
    } 
} 

有沒有辦法使抽象函數可選或具有默認值?

class EmptyControllerExample extends Controller { 
    public function something(){} 
} 

或者什麼是最好的方法去做這件事?

+2

在Controller抽象類中給它一個默認的主體,即使它只是'return;'。然後在需要它的子類中覆蓋它。沒有像「可選抽象方法」這樣的東西。 –

+0

我收到以下錯誤:'抽象函數App \ Http \ Controllers \ Controller :: Upload()不能包含主體'你能舉一個例子嗎? – jagmitg

+0

@JSG因爲它不能是'抽象的'並且有一個身體。如果它有一個body,你不能在方法sig中使用'abstract'。 –

回答

0

父類中的抽象函數只能在您的應用程序需要它在繼承它的所有控制器中實現以下方法時才使用,顯然情況並非如此。

在這種情況下,我會做一個trait。在這裏你創建一個trait,可以由需要它的類來實現。請注意0​​關鍵字的使用,use somethingTrait;

trait somethingTrait 
{ 
    public function something() 
    { 
     echo "something called"; 
    } 
} 

class Controller 
{ 
    use somethingTrait; 

    public function run() 
    { 
     $this->something(); 
    } 
} 

phpfiddle link

另一種形式給出可以做一個class繼承結構,如果你想控制器實現方法都有一些共同點。您可以在CrmController的哪個位置實施您的特殊方法,您仍然可以在抽象控制器中創建共享methods

        AbstractController 
             | 
            CrmController 
             | 
            CompanyController 

對於你的問題'有無論如何使抽象函數可選或具有默認值?'不,如果您試圖將抽象函數設爲可選,那麼您就錯了。希望我的建議可以幫助。

0

不可能有一個abstract方法可選,因爲它暗示在PHP中,所有的抽象方法必須有一個實現。

有合法的使用情況可選抽象方法,是:事件處理,元數據描述者,等等。不幸的是,你需要使用常規,非抽象方法有一個空的身體,並在PHPDoc的指示他們什麼也不做,除非擴展。

不過要小心:這可以很快地變成代碼味道,通過與他們的孩子分享班級責任。如果您正在處理通用事件,則可以查看Laravel's own event systemObserver pattern