Chciałem utworzyć interfejs w PHP, ale nie chciałem, aby był zbyt restrykcyjny w kwestii typu argumentów, które zaakceptowałby w jednej z publicznych metod. Nie chciałem zrobićInterfejs PHP akceptuje argument interfejsu?
interface myInterface {
public function a(myClass $a);
}
Bo nie chce przekazać go instancję myClass
. Ale chcę mieć pewność, że obiekt przekazany spełnia pewne parametry, które mogłem osiągnąć poprzez zdefiniowanie interfejsu. Więc pomyślałem, aby określić klas, które wykorzystują interfejsy, tak jak poniżej:
<?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) {}
}
Ale pojawia się błąd PHP Fatal error: Declaration of obj::takes_a() must be compatible with iC::takes_a(iA $a) on line 15
Czy istnieje sposób upewnić się, że argument akceptuje tylko klasę pewnego interfejsu? A może nadwerężyłem/nad-inżynierię tego?
kiedy zaimplementować interfejs, podpis metod musi być taka sama, jak w interfejsie. ('public function takes_a (iA $ a);' w twojej klasie obj), ale możesz przekazać jabłko na tym przykładzie. '$ o = new obj(); $ o-> takes_a (new apple()); ' –
@ RaphaelMüller Nie rozumiem, co mówisz - wiem, jak przekazać obiekt Apple. Dodanie linii do końca skryptu nie powoduje jej kompilacji; nadal narzeka, że podpis funkcji nie jest zgodny. – user151841
patrz https://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29. Przez zawężenie 'takes_a()', aby zezwolić tylko na "jabłko", uniemożliwiasz innym "iA", ale interfejs iC wymaga akceptacji _any_ iA jako parametru. – VolkerK