Czy klasa może rozszerzyć klasę i zaimplementować interfejs


100

Czy klasa może rozszerzyć zarówno interfejs, jak i inną klasę w PHP?
Zasadniczo chcę to zrobić:

interface databaseInterface{
 public function query($q);
 public function escape($s);
 //more methods
}

class database{ //extends both mysqli and implements databaseInterface
 //etc.
}

Jak można to zrobić, po prostu robiąc:

class database implements databaseInterface extends mysqli{ 

powoduje błąd krytyczny:

Błąd analizy: błąd składni, nieoczekiwany T_EXTENDS, oczekiwanie „{” w * pliku * w wierszu * w wierszu *

18
Jak to jest zbyt zlokalizowane ?! „To pytanie raczej nie pomoże przyszłym gościom”. Jednak najlepsza odpowiedź ma 33 głosy za, a pytanie 4 gwiazdki!
duality_

Odpowiedzi:


177

Spróbuj na odwrót:

class database extends mysqli implements databaseInterface { ...}

To powinno działać.


Ach, bardzo dziękuję. Dlaczego właściwie jest tak, że mają być na odwrót?
Pim Jager

14
Ponieważ możesz dziedziczyć tylko jedną klasę i możesz zaimplementować dowolną liczbę interfejsów, prawdopodobnie była to kwestia cukru składniowego. Pamiętaj też, że jeśli Twoja podklasa implementuje jakiekolwiek interfejsy, pojawi się to również na liście zaimplementowanych metod. Więc umieszczenie ich w takiej kolejności ma pewien sens.
Drew

Czy to zła praktyka?
Mohammed Shamshid

21

Tak, może. Wystarczy zachować odpowiednią kolejność.

class database extends mysqli implements databaseInterface { ... }

Ponadto klasa może implementować więcej niż jeden interfejs. Po prostu oddziel je przecinkami.

Czuję się jednak zobowiązany do ostrzeżenia, że rozszerzenie klasy mysqli to niesamowicie zły pomysł . Dziedziczenie samo w sobie jest prawdopodobnie najbardziej przereklamowaną i nadużywaną koncepcją w programowaniu obiektowym.

Zamiast tego radziłbym robić rzeczy związane z db metodą mysqli (lub sposobem PDO).

Poza tym drobiazg, ale konwencje nazewnictwa mają znaczenie. Twoja klasa databasewydaje się wtedy bardziej ogólna mysqli, dlatego sugeruje, że ta ostatnia dziedziczy po, databasea nie odwrotnie.


1
Dlaczego rozszerzenie klasy mysqli to zły pomysł?
Pim Jager

11
Po pierwsze, ponieważ to nie jest twoje. Kiedy faceci mysqli zdecydują się coś zmienić, zachowanie podklasy również się zmieni. Po drugie, dziedziczenie służy do SPECJALIZACJI, a nie ROZSZERZANIA o dodatkowe funkcje. To jest najbardziej niezrozumiana rzecz w OOP. Zasadniczo staram się rozszerzać tylko klasy abstrakcyjne.
Michał Rudnicki

Michał - czym zmiana w mysqli byłaby inna dla programisty stosującego podejście polimorficzne od zagregowanego / skomponowanego? Nadal będziesz musiał zaktualizować kod, aby obsłużyć zmiany.
Peter Bailey

2
Znam wzór adaptera. Mówię tylko, że jeśli nazwa metody ulegnie zmianie lub stanie się przestarzała, nadal będziesz musiał zmienić kod w obu scenariuszach. Chociaż zgadzam się, że podejście niepolimorficzne jest lepsze w tym scenariuszu, nie wierzę, że adapter byłby „odporny” na zmiany.
Peter Bailey

2
Będziesz musiał zmienić tylko kod adaptera, a nie wszystkie miejsca używające tego kodu. Dzięki kompozycji możesz zapewnić warstwę kompatybilności bez względu na wszystko, podczas gdy dzięki dziedziczeniu możesz w najlepszym razie nazwać to hackiem. I, skorygowałem, adapter zapewniłby lepszą odporność na zmiany.
Michał Rudnicki

6

tak, w rzeczywistości, jeśli chcesz zaimplementować wiele interfejsów, możesz zrobić to w następujący sposób:

public class MyClass extends BaseClass implements myInterface1, myInterface2, myInterface3{ 

}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.