2015-10-14 141 views
5

我想在PHP中創建一個接口,但是我不希望它在一種公共方法中接受的參數類型太過於限制。我不想做PHP接口接受接口參數?

interface myInterface { 
    public function a(myClass $a); 
} 

因爲我可能不希望通過它的myClass一個實例。但是,我確實希望確保傳遞的對象符合某些參數,我可以通過定義一個接口來完成這些參數。因此,我認爲,指定使用的接口類,就像這樣:

<?php 

interface iA {} 
interface iB {} 

interface iC { 
    public function takes_a(iA $a); 
    public function takes_b(iB $b); 
} 

class apple implements iA {} 
class bananna implements iB {} 

class obj implements iC { 
    public function takes_a(apple $a) {} 
    public function takes_b(bananna $b) {} 
} 

但是,我得到的錯誤PHP Fatal error: Declaration of obj::takes_a() must be compatible with iC::takes_a(iA $a) on line 15

是否有辦法確保參數只接受一類特定接口的?或者,我是否在過度使用/過度設計?

+0

,這些方法的簽名必須是相同的接口。 (公共函數takes_a(iA $ a);'在你的obj類中),但是你可以在這個實例上傳遞蘋果。 '$ o = new obj(); $ o-> takes_a(new apple());' –

+0

@RaphaelMüller我不明白你在說什麼 - 我知道如何傳遞一個蘋果對象。將腳本添加到腳本的末尾不會使其編譯;它仍然抱怨函數簽名不匹配。 – user151841

+4

請參閱https://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29。通過縮減'take_a()'來僅允許「蘋果」,你不允許其他「iA」,但iC接口要求接受_any_ iA作爲參數。 – VolkerK

回答

3

你的概念是完全正確的。只有一個小小的錯誤部分。您的類方法必須具有與您的界面中指定的簽名相同的簽名。

爲VolkerK說:

看到wikipedia。通過縮小takes_a()僅允許「蘋果」,您不允許其他「iA」,但iC接口要求接受任何iA作爲參數。 - VolkerK

考慮到這一點看到更正後的代碼:

<?php 

interface iA { 
    function printtest(); 
} 
interface iB { 
    function play(); 
} 

//since an interface only have public methods you shouldn't use the verb public 
interface iC { 
    function takes_a(iA $a); 
    function takes_b(iB $b); 
} 

class apple implements iA { 
    public function printtest() 
    { 
     echo "print apple"; 
    } 
} 
class bananna implements iB { 
    public function play() 
    { 
     echo "play banana"; 
    } 
} 

//the signatures of the functions which implement your interface must be the same as specified in your interface 
class obj implements iC { 
    public function takes_a(iA $a) { 
     $a->printtest(); 
    } 
    public function takes_b(iB $b) { 
     $b->play(); 
    } 
} 

$o = new obj(); 

$o->takes_a(new apple()); 
$o->takes_b(new bananna()); 
當你實現你的界面