Ich weiß, ich kann Methoden in PHP nicht überladen. Und soweit ich weiß, sind private
-Methoden in einer Klasse für Klassen unsichtbar, die die Basisklasse erweitern. Warum funktioniert das nicht?
Der Fehler:
PHP Strict Standards: Declaration of Child::foo() should be compatible with Base::foo($arg) in /var/www/boludo.php on line 17
Ich nahm an, dass die Methode foo($arg)
in der Klasse Child
unsichtbar ist, weil private
ist. Also, ich überbelaste foo
nicht, ich erstelle nur eine Methode namens foo
.
Um den Hinweis zu korrigieren, ändern Sie einfach foo()
im Child zu
Zur Frage "Warum funktioniert das nicht?":
Die Sichtbarkeit in PHP bezieht sich ausschließlich auf den Laufzeitzugriff. Es beeinflusst nicht, wie Sie Klassen und Methoden erweitern / verfassen / überladen können. Wenn Sie die Sichtbarkeit einer privaten Methode von einem Supertyp in einem Subtyp entfernen, wird eine separate Methode im Subtyp hinzugefügt, die nicht auf dieselbe benannte Methode im Supertyp zugreifen kann. PHP wird jedoch für diese eine Eltern-Kind-Beziehung annehmen. Das hat die Benachrichtigung jedoch nicht verursacht. Zumindest nicht auf eigene Faust.
Der Grund, warum Sie den Hinweis bekommen, ist, dass Sie dann auch versuchen, die Methodensignatur zu ändern. Für Ihre foo()
muss nicht mehr $arg
an sie übergeben werden. Wenn Sie eine Eltern-Kind-Beziehung zwischen den Methoden annehmen, ist das ein Problem, weil das Liskow-Substitutionsprinzip angibt, dass "Wenn S ein Untertyp von T ist, dann können Objekte des Typs T durch Objekte des Typs S ersetzt werden, ohne das Programm zu unterbrechen. Mit anderen Worten: Wenn Sie Code haben, der Base
verwendet, sollten Sie in der Lage sein, Base
durch Child
zu ersetzen, und das Programm sollte immer noch so arbeiten, als ob es Base
verwendet hätte.
Angenommen, Ihre Base
hat auch eine öffentliche Methode bar()
.
Stellen Sie sich jetzt Child
changes bar()
vor, um ein Argument zu verlangen. Wenn Sie dann Child
für Base
an den Client übergeben, brechen Sie den Client, weil der Client $base->bar();
ohne ein Argument aufruft.
Offensichtlich könnten Sie den Client ändern, um ein Argument zu übergeben, aber dann hängt der Code wirklich davon ab, wie Child
die Methode definiert hat, also ist der Typhint falsch. Tatsächlich ist Child
kein Base
, weil es sich nicht wie ein Base
verhält. Es ist dann Erbschaft gebrochen.
Nun das Lustige ist, wenn Sie das $arg
von foo()
entfernen, verletzen Sie technisch LSP nicht, weil der Client immer noch funktionieren würde. Die Nachricht ist hier falsch. Das Aufrufen von $base->foo(42)
in einem Client, der zuvor Base
verwendet hat, funktioniert immer noch mit einem Child
, weil% code_de% das Argument einfach ignorieren kann. Aber PHP möchte, dass Sie das Argument optional machen.
Beachten Sie, dass LSP auch auf die Rückgabe einer Methode angewendet wird. PHP enthält nur den Rückgabetyp in der Signatur nicht, so dass Sie dies selbst berücksichtigen müssen. Ihre Methoden müssen zurückgeben, was der Supertype zurückgegeben hat oder was verhaltensmäßig äquivalent ist.
Sie können das Überladen von Funktionen in PHP mit der Funktion __call durchführen: Ссылка
Abgesehen davon besteht Ihr Problem darin, dass Sie auf diese Weise gegen das Prinzip der Substituierbarkeit verstoßen: Ссылка
Etwas, das PHP benutzt. Auf diese Weise wird die Ersetzbarkeit verletzt, wenn Sie ein Objekt vom Typ Basistyp durch eines mit dem Typ Child ersetzen. Sie ändern die Schnittstelle der Basisklasse in der abgeleiteten Klasse und entfernen das Argument der Methode foo (...). Auf diese Weise können Objekte der Basisklasse nicht durch Objekte der Klasse Child ersetzt werden, ohne das Programm zu unterbrechen. damit verletzt Liskovs Substituierbarkeitsprinzip (LSP).
Tags und Links php oop method-overloading