2010-08-20 11 views
6

Quindi, questa è l'ultima domanda di ereditanza fastidiosa che ho avuto per un po 'quindi volevo andare avanti e chiedere. Quindi darò un esempio in PHP:?Ereditarietà sotto il cofano

<?php 

class Base 
{ 
    private $z = 4; 


    function GetPrivate() 
    { 
     echo $this->z; 
    } 

} 

class Derived extends Base 
{ 
} 

$b = new Base(); 
$d = new Derived(); 

$d->GetPrivate(); 

>

abbastanza semplice. Quando ho sempre letto sull'ereditarietà, la spiegazione era semplicemente "si eredita il pubblico e i membri protetti" e basta. Quello che non capisco sono un paio di cose su come l'interprete in questo esempio spiega cosa appartiene a cosa.

Ad esempio, quando si crea una classe derivata, sono in grado di utilizzare la funzione pubblica "GetPrivate" della Base per ottenere le variabili private della classe base. Tuttavia, la semplice definizione di ereditarietà non funziona con questo per me. Ciò che intendo è che eredito il metodo GetPrivate ma ho ancora una sorta di collegamento a variabili private solo da quel metodo che apparteneva alla classe base (anche se $ si riferisce all'oggetto classe derivata). Non sono riuscito a creare una nuova funzione nella classe derivata per accedere a tali variabili private.

Così, l'interprete tiene sotto controllo le funzioni ereditate dalla classe base e i possibili collegamenti che tengono a membri privati ​​disponibili solo per quella classe base?

risposta

2

L'interprete (o il compilatore in altro linguaggio OOP), controlla l'accesso un passo alla volta.

Quando si chiama $d->GetPrivate();, l'interprete verificare il contesto in questo è la principale (contesto pubblico, come presumo che non sei in una classe correlate a Drerived o Base) e GetPrivate() è un metodo pubblico. Pertanto, $d->GetPrivate(); è consentito in questo contesto, quindi nessun errore.

In GetPrivate(), il contesto è $d oggetto come Base e l'accesso a z è un elemento privata dell'oggetto corrente ($d). Quindi l'accesso è valido.

Il concetto che viene qui a giocare è "Nascondere dati" (controllo accessi) e "Incapsulamento" (combinazione di dati e funzione).

L'ereditarietà di riprodurre solo per consentire GetPrivate() di Base da utilizzare in quanto appartiene a un oggetto di Derived.

È vero che esiste ancora un collegamento a un dato privato ma tale collegamento non è diretto. L'importanza è che l'accesso avviene come classe Base consentita.

Quindi, per rispondere alla tua domanda è:

SI! L'interprete tiene sotto controllo le funzioni ereditate dalla classe base e i possibili collegamenti che tengono ai membri privati ​​disponibili solo per quella classe base.

Spero che questo aiuti.

2

La risposta è un semplice sì, provare questo fuori:

<?php 


class Base 
{ 
    private $z = 10; 

    public function getPrivate() 
    { 
     return $this->z; 
    } 
} 


class Derived extends Base 
{ 
    public function getPrivate() 
    { 
     return $this->z; 
    } 
} 

$a = new Derived(); 

echo $a->getPrivate(); 

vedrete che ora che abbiamo definito getPrivate sulla classe Derived possiamo accedere più z nel Base sin dal suo privato, se vogliamo essere in grado di accedervi dalla classe derivata, dobbiamo dichiararlo protetto invece che privato.

1

Beh, non posso dire molto circa i dettagli parser, ma la chiave di lettura è nella comprensione di ciò che significa visibility:

I membri della classe dichiarati pubblico si può accedere ovunque. I membri dichiarati protetti sono accessibili solo all'interno della classe stessa e per classi ereditate e padre. I membri dichiarati come privati ​​possono essere raggiunti solo dalla classe che ha definito il membro.

Now, the PHP manual also states:

Ad esempio, quando si estende una classe, la sottoclasse eredita tutti i metodi pubblici e protetti dalla classe padre. A meno che una classe non sostituisca tali metodi, manterranno la loro funzionalità originale.

Se fate una var_dump($d) sulla classe derivata, si vedrà che contiene Base->z:

object(Derived)#2 (1) { 
    ["z":"Base":private]=> 
    int(4) 
} 

Quindi non v'è un riferimento a z in base, ma è privato e dal mezzo privato gli Stati è possibile accedere solo alla classe che definisce il membro, non è possibile accedervi da Derivato.

Offrendo metodi pubblici in Base per accedere al membro privato, si controlla efficacemente l'accesso tramite il metodo padre. Forse $z è qualcosa che deve essere letto solo nelle classi estese, ad esempio un adattatore di database.

Questo è il nascondiglio delle informazioni e il controllo degli accessi. Non significa, se estendi Base, perderai $ z. L'ereditarietà è una relazione -a. Derivato è-a Base e come tale, ha un $ z, anche se non su se stesso ma attraverso il suo genitore.

Problemi correlati