Moin!
Wenn ich eine Klasse erweitere, und eine als protected vererbte Methode neu als public implementiere, dann bringt mir das erstmal keinerlei Vorteile, wenn ich den Namen beibehalte. Sprich: Ich kann genausogut auch einen neuen Namen vergeben, ohne Unterstrich. Denn die neue Methode ist ja einfach so aufrufbar, ohne automatisch irgendwie die vererbte Methode aufzurufen.
Die neue überschreibt aber die alte, was ja durchaus nicht unsinnig ist, wenn der alte Klassencode diese Methode anspricht und nun auf meiner neuen, erweiterten/geänderten/korrigierten landen soll. Ansonsten hätte ich in dem Fall zwei Methoden, eine neue unterstrichlose mit der neuen Implementation und eine alte, die den Code der neuen aufruft. Das wird am Ende nicht weniger verwirrend als der falsch gewordene Unterstrich.
Alles, was in einer Klasse protected oder private ist, ist Bestandteil der internen Implementierung dieser Klasse, und hat den außenstehenden Nutzer der Klasse nicht zu interessieren.
Wenn du jetzt diese Klasse erweitern willst, bist du zwar auch Nutzer, aber kein richtig außenstehender mehr. Und wenn du mit deiner erweiternden Klasse jetzt das Public-Interface um eine neue Methode ergänzen willst, kannst du das ja gern tun. Die Namenskonvention sagt: Public ohne Unterstrich vorneweg.
public function foo (){}
Es bringt dir an diesem Punkt keinerlei Vorteil, die Methode _foo als public zu deklarieren, da du sie dann ja ohnehin implementieren müsstest:
public function _foo () {}
Von alleine ohne Code ruft dir diese Funktion halt nicht automatisch die protected function _foo der Originalklasse auf.
Was diese neue Methode foo tun soll, ist komplett dir überlassen. Wenn sie einfach nur die interne Methode _foo aufrufen soll, damit diese öffentlich verfügbar wird, dann muss sie das tun:
public function foo ()
{
return $this->_foo();
}
Und wenn dir die Implementation der Originalfunktion _foo in der Originalklasse nicht gefällt, dann baust du dir einfach was eigenes dazu:
protected function _foo () {}
Und wenn diese Methode das Original-_foo aufrufen soll:
protected function _foo ()
{
return 'my' . parent::_foo();
}
Du hast also wirklich jegliche Möglichkeit, alle denkbaren Konstruktionen zu bauen, ohne dass du die Ordnung des Methoden-Namensraumes durcheinander bringen musst.
Es dreht sich hierbei ja in erster Linie um ein Planungsproblem: Wieso hat der Autor der Originalklasse geplant, dass _foo nur protected ist? Und wieso glaubst du als Autor der Erweiterungsklasse, dass _foo unbedingt public gehört? Und warum ausgerechnet unter diesem Namen?
Nur wenn man sich innerhalb der Klasse befindet. Von außen geht parent:: natürlich nicht. Irgendwie finde ich das nicht gerade clever, wenn der alte Klassencode _foo() nimmt und ein darauf aufbauendes Projekt foo() verwendet. Kann man dem "alten" Programmierer zum Vorwurf machen, dass er nicht vorausgesehen hat, dass der "neue" die betroffene Funktionalität anders und nun öffentlich haben möchte?
Hehe, wenn alle Stricke reißen, kannst du dir immer noch was mit Reflection hinbasteln. ;)
Ich bin persönlich aber absolut kein Fan von sowas. Expliziter Code ist immer besser, als irgendwelche Automagie und der Weg von hinten durch die Brust ins Auge.
- Sven Rautenberg