2012-10-24 18 views
19

mi hanno difficoltà a comprendere il motivo per cui si ottiene l'uscita di questo codice:Ereditarietà e visibilità - 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(); 
?> 

Così Foo estende Bar. $ myfoo è un obetto della classe Foo. Foo non ha un metodo, chiamato test(), quindi lo estende dalla barra principale. Ma perché il risultato del test() è

Bar::testPrivate 
Foo::testPublic 

Si può spiegare a me perché il primo non è Pippo :: testPrivate, quando il metodo di questo genitore viene sostituita nel bambino?

Grazie mille in anticipo!

risposta

13

Probabilmente perché testPrivate è, come già suggerisce il nome, un metodo privato e non verrà ereditato/sovrascritto dall'ereditarietà della classe.

Sulla pagina di manuale php.net probabilmente ottenuto che il codice da esso esplicitamente afferma che We can redeclare the public and protected method, but not private

Allora, che cosa succede esattamente è la seguente: La classe bambino non ridichiarare il metodo testPrivate ma invece crea la sua propria versione nello "scope" se solo l'oggetto child. Poiché test() è definito nella classe genitore, accederà ai genitori testPrivate.

Se si dichiara la funzione test nella classe figlio, è necessario accedere al metodo figlio ? testPrivate().

3

Dal manual:

Utenti dichiarato come privato può accedere solo dalla classe che definisce il membro.

Poiché la funzione di test viene eseguita nella barra della classe base, accederà alla funzione privata nella propria classe.

5

private I membri non possono essere ignorati, solo quelli pubblici e protetti possono. Significa che, in effetti, testPrivate è non sostituito, quindi Bar non può vederlo e chiama ancora il proprio testPrivate.

5

I metodi privati ​​non sono visibili a nient'altro che alla classe dichiarante. Dato che chiami testPrivate dalla classe genitore, l'unico metodo a cui ha accesso è la propria dichiarazione del metodo. In questo modo ottieni l'output che vedi. Se il modificatore di accesso fosse stato protected, tuttavia, si otterrebbe l'output previsto, poiché i metodi protetti sono visibili in tutta la catena di ereditarietà.

5

Perché private significa private. Nessun'altra classe, nemmeno le classi di bambini conoscono Bar::testPrivate() e quindi non possono ignorare qualcosa di cui nemmeno sono a conoscenza.

È possibile utilizzare Foo::testPrivate() solo all'interno di . Perché questo è ciò che è private.

Maggiori informazioni: Strange behavior when overriding private methods

3

Questo non è PHP specifiche.Le regole di ereditarietà richiedono che le funzioni protette e pubbliche siano superflue. Le funzioni private hanno il loro scopo e sono invisibili per la classe generalizzata.

riporta qui di seguito la stessa situazione in Java, stesso risultato:

Bar::testPrivate 

Foo::testPublic 

Tranne si potrebbe ottenere un avvertimento

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

dal Java viene compilato.

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(); 
    } 
}