2012-10-24 14 views
19

mam trudności ze zrozumieniem, dlaczego mamy wyjście ten kod:Dziedziczenie i widoczność - PHP

<?php 

class Bar 
{ 
    public function test() { 
     $this->testPrivate(); 
     $this->testPublic(); 
    } 

    public function testPublic() { 
     echo "Bar::testPublic\n"; 
    } 

    private function testPrivate() { 
     echo "Bar::testPrivate\n"; 
    } 
} 

class Foo extends Bar 
{ 
    public function testPublic() { 
     echo "Foo::testPublic\n"; 
    } 

    private function testPrivate() { 
     echo "Foo::testPrivate\n"; 
    } 
} 

$myFoo = new foo(); 
$myFoo->test(); 
?> 

Więc Foo rozciąga Bar. $ myfoo to pozycja klasy Foo. Foo nie ma metody zwanej test(), więc rozszerza ją z paska nadrzędnego. Ale dlaczego wynik testu() jest

Bar::testPrivate 
Foo::testPublic 

Czy możesz mi wyjaśnić, dlaczego najpierw nie Foo :: testPrivate, gdy metoda rodzica jest przesłonięta u dziecka?

Dziękuję bardzo z góry!

Odpowiedz

13

Prawdopodobnie testPrivate jest, jak sama nazwa wskazuje, metodą prywatną i nie zostanie odziedziczone/nadpisane przez dziedziczenie klas.

Na php.net stronie podręcznika prawdopodobnie dostał ten kod od niej jawnie mówi, że We can redeclare the public and protected method, but not private

Więc, co dokładnie się dzieje, jest następujący: Klasa dziecko nie będzie redeclare metodę testPrivate lecz tworzy własną wersję w "zasięgu", jeśli tylko obiekt podrzędny. Ponieważ klasa test() jest zdefiniowana w klasie nadrzędnej, uzyska dostęp do rodziców testPrivate.

Jeśli chcesz redeclare funkcji test w klasie potomnej, powinien uzyskać dostęp do metody childs ? testPrivate().

3

Z manual:

Członkowie zadeklarowane jako prywatny może być dostępna tylko przez klasę, która wyznacza członka.

Gdy twoja funkcja testowa działa na pasku klasy podstawowej, uzyska dostęp do funkcji prywatnej w swojej klasie.

5

private członków nie można przesłonić, tylko publiczne i chronione mogą. Oznacza to, że w rzeczywistości testPrivate nie jest nadpisywany, więc ,, nie może go zobaczyć i nadal wywołuje swoją własną nazwę: testPrivate.

5

Prywatne metody nie są widoczne dla niczego poza klasą deklarującą. Ponieważ wywołujesz testPrivate z klasy nadrzędnej, jedyną dostępną metodą jest własna deklaracja metody. W ten sposób otrzymasz wynik, który widzisz. Gdyby jednak modyfikator dostępu miał wartość protected, otrzymalibyśmy oczekiwaną wydajność, ponieważ metody chronione są widoczne w całym łańcuchu dziedziczenia.

5

Ponieważ private oznacza private. Żadna inna klasa, nawet klasy dzieci nie wiedzą o Bar::testPrivate() i dlatego nie mogą przesłonić czegoś, o czym nawet nie wiedzą.

Możesz używać Foo::testPrivate() tylko wewnątrz Foo. Bo o to właśnie chodzi w tym private.

Więcej informacji: Strange behavior when overriding private methods

3

To nie jest PHP specyficzne.Reguły dziedziczenia wymagają nadpisywania zabezpieczonych i publicznych funkcji. Prywatne funkcje mają własny zakres i są niewidoczne dla uogólnionej klasy.

Tutaj znajdziesz takiej samej sytuacji w Javie, sam rezultat:

Bar::testPrivate 

Foo::testPublic 

wyjątkiem ciebie może dostać ostrzeżenie

The method testPrivate() from the type Foo is never used locally Foo.java  

ponieważ Java jest skompilowany.

public class Bar 
{ 
    public void test() { 
     this.testPrivate(); 
     this.testPublic(); 
    } 

    public void testPublic() { 
     System.out.println("Bar::testPublic\n)"); 
    } 

    private void testPrivate() { 
     System.out.println("Bar::testPrivate\n"); 
    } 
} 

public class Foo extends Bar { 
    public void testPublic() { 
     System.out.println("Foo::testPublic\n"); 
    } 

    private void testPrivate() { 
     System.out.println("Foo::testPrivate\n"); 
    } 

    public static void main(String[] args) { 
     Foo myFoo = new Foo(); 
     myFoo.test(); 
    } 
}