Pozwól, że poszerzę Twój przykład by pokazać IMHO głupotę PHP...
<?php
class C{
private $property = 'valueC';
public function echoPrivateProperty(A $object){
}
}
class B extends C{
private $property = 'valueB';
}
class A extends B{
private $property = 'valueA';
}
$c = new C();
$b = new B();
$a = new A();
$c->echoPrivateProperty($a);// valueC
$b->echoPrivateProperty($a);// valueC
$a->echoPrivateProperty($a);// valueC
var_dump($c);// object(C)#1 (1) { ["property":"C":private]=> string(6) "valueC" } var_dump($b);// object(B)#2 (2) { ["property":"B":private]=> string(6) "valueB" ["property":"C":private]=> string(6) "valueC" } var_dump($a);// object(A)#3 (3) { ["property":"A":private]=> string(6) "valueA" ["property":"B":private]=> string(6) "valueB" ["property":"C":private]=> string(6) "valueC" } ?>
Powiedz mi jedno... Dlaczego dziedziczona metoda echoPrivateProperty zgłupiała i ZAWSZE pokazuje valueC, mimo, że w klasie A oraz B a także C
mam własność $property ustawioną na, odpowiednio 'valueA', 'valueB', 'valueC' i niezależnie od obiektu wywołujacego powinna być pokazana, wedle tego co widnieje w ciele metody, wartość 'valueA' ? W końcu mam taką w klasie A... Wersja PHP 5.3.3

Idziemy dalej... Modyfikujemy sobie nieco klasę B do postaci:
class B extends C{
private $property = 'valueB';
public function echoPrivateProperty(A $object){
}
}
i co dostajemy?
$c->echoPrivateProperty($a);// valueC
$b->echoPrivateProperty($a);// valueB
$a->echoPrivateProperty($a);// valueB
W efekcie mamy jeszcze większe zaciemnienie, ponieważ teraz metodę dziadka przesłoniliśmy metodą rodzica. Jaki z tego morał? Metoda klasy przodka wywoła odwołanie do "swoich" danych utworzonych niejawnie podczas tworzenia obiektu pochodnego. Utworzy więc coś na kształt jego instancji, którą bardzo ładnie widać w var_dumpie i każda metoda przodka, jeśli tylko nie jest przesłonięta, będzie się do "instancji" tego przodka odnosić

Bardzo dobrze to widać poprzez dodanie do wszystkich klas zmiennej prywatnej o tej samej nazwie. Ciało metody tak napisanej powinno użyć pola $property obiektu przekazanego w parametrze, czyli wyświetlić 'valueA'... Nie robi jednak tego ale odwołuje się do wartości prywatnej obiektu klasy, która ową metodę definiuje lub przesłania

To jest po prostu głupota maksymalna, która stoi w jawnej sprzeczności z logiką tego co stoi jak wół w metodzie

Jaki jest morał numer 2? Nie ma w PHP czegoś takiego jak mówimy oboje, ale zupełnie inny mechanizm, który w ciele klasy pochodnej "w tle" odpala sobie konstruktor przodków począwszy od "roota" i stąd ma dostęp do właściwych mu pól przodków oraz dopasowuje metody do takich jakie zna począwszy od "roota", ewentualnie je nadpisując.
PS.: Zapomniałbym zwrócić Ci uwagę na przykład drugi, gdzie przysłaniałem metodę... Popatrz do jakiej sytuacji doprowadziłem. Obiekt C wywołuje metodę klasy A, która jest już przeslonięta przez klasę B. Na logikę więc patrząc całość kompletnie nie trzyma się kupy. Widząc zwracane wartości można dojść do wniosku, że wywoływany jest nie A $object->property, ale $this->property klasy ową metodę implementujący lub nadpisujący. Jako że C nie ma przodka, to wywoła ją dla siebie, ale B ją nadpisuje, więc wywoła ją dla swojej $property. Z kolei A nie ma metody nadpisującej, więc przejmuje ją z obiektu rodzica, czyli B i to jego $property wyświetla. Cuda na kiju, bo logiki to się żadnej nie trzyma. To dlatego też metoda ta wyświetlała zawsze 'valueC', ponieważ wcześniej jedynie klasa C ją implementowała. A że ani B ani A nie nadpisywały to wszystkie wyświetliły $property klasy C, która tę metodę wprowadziła. Zwyczajnie niedopatrzenie lub jakaś pokrętna logika. Dla mnie to pogwałcenie zasad obiektówki i coś, co uznaję zwyczajnie za błąd, odstępstwo od niej.
Dla mnie to co w tym momencie zrobiło PHP jest nieakceptowalne. Kompletny galimatias, który nie powinien mieć miejsca. W przypadku bowiem gdyby to działało jak powinno, w Twojej wersji kodu -bez przeróbek, wywołanie $c->echoPrivateProperty($a); powinno zwrocić "Attribute $property doesn't exists in class A". Tak więc to nie jest jakieś "cudowne" dziedziczenie własności prywatnych po przodku tylko jakieś chamskie i na pałę dzialanie, które z dziedziczeniem nie ma nic wspólnego. To jakiś idiotyzm, który pewnie twórcy języka nieświadomie stworzyli. Dla mnie to błąd poważny, ponieważ zauważ co robi z pamięcią. Jeśli każda klasa poprzednia jest duża, to dziedzicząc łańcuchem po kilku i tworząc obiekt ostatniej w pamięci mamy po prostu horror zależności metod i obiekt-kolos. Nie wiem jak Ty, ale dla mnie takie rozwiązanie nie jest akceptowalne jako prawidłowe. To jakaś próba obejścia dostępu do zmiennych, do których nie powinno się miec dostępu i złamanie enkapsulacji najprościej mówiąc. Nie wiem kto to wymyślił, kto to impleentował, ale według mnie należą mu się ostre baty.