am 15. Mai 2009
Heute wollen wir mal einen kleinen Wettstreit zwischen abstrakten Klassen und Interfaces starten. Vielleicht mache ich ja eine Reihe draus. Mal schauen wie es ankommt. Da es in der PHP Gemeinde leider nicht sehr verbreitet ist Interfaces einzusetzen, möchte ich doch mal eine Lanze brechen und mal einen Vorteil der Interfaces gegenüber anderer Objektorientierter Konstrukte aufzeigen.
Ich kann mich noch an eine Diskussion an einen Ex-Arbeitskollegen erinnern, der meinte, dass abstrakte Klassen alles hergeben, was ich mit Interfaces machen kann. Sie wären sozusagen unnötig. Ich hoffe, dass er dies liest und morgen anderer Meinung ist. Naja vielmehr hoffe ich, dass ich mein Argument so gut formulieren kann, dass er es kapiert.
Also fangen wir an. Interfaces sind dazu da das Verhalten einer Klasse nach außen festzulegen. Wenn ich das Interface kenne, gegen das eine Klasse programmiert wurde, so muss mich nicht interessieren, wie es umgesetzt wurde. Ich kann es einfach verwenden. Und das tolle daran ist: jede Klasse, die dieses Interface implementiert kann einfach durch eine andere ausgetauscht werden. Super Sache. Aber die Verfechter von abstrakten Klassen werden jetzt sagen: “Moment mal, das kann ich auch!”. Was macht man in einem solchen Fall? Beispiele zeigen.
interface Countable
{
public function count( );
}
abstract class Countable
{
abstract public function count( );
}
Tja dumm gelaufen. Diese zwei Varianten sind wirklich gleich mächtig. Beide zwingen einen dazu die Funktion count zu implementieren und beide können beim Typehinting verwendet werden. Ich würde mal sagen, es steht also immer noch 0:0 in unserem kleinen Wettstreit. Was machen wir jetzt aber wenn wir noch ein “Interface” haben. Nehmen wir ein Sortable Interface.
interface Sortable
{
public function sort( );
}
abstract class Sortable
{
abstract public function sort( );
}
Und wieder ist es genau das gleiche. War ja auch zu erwarten, ich habe ja einfach nur die Namen ausgetauscht. Jetzt will ich aber eine Klasse haben, die sowohl Countable als auch Sortable ist. Tooooor. 0:1 für das Interface. Interfaces haben die wunderbare Eigenschaft, dass hier “Mehrfachvererbung” geht, was bei Klassen nicht funktioniert. Was auch gut ist, denn bei Klassen bekommt man leicht Probleme dabei (siehe Diamantenproblem). Ich kann also ohne Probleme beide Interfaces implementieren. Sobold ich mich aber für eine Superklasse (Elternklasse) entschieden habe, habe ich mir den kompletten Abteilungsbaum zugemacht.
Wenn es unbedingt nötig sein sollte, kann man ja getrost trotzdem von der abstrakten Klassen ableiten. Das natürlich nur, wenn dort schon Funktionalitäten verortet sind, die man benötigt. Abstrakte Klassen haben aber auch ihr Einsatzgebiet, dass ich euch aber ein ander mal verraten werde. Ich habe ja schließlich noch eine Menge von Artikel vor mir.
Eine Sache möchte ich euch noch mitgeben: Benutzt Interfaces!!! Die Dinger sind so schön und nützlich.