2010-08-20 16 views
6

Also, das ist die letzte erbitterte Erbschaftsfrage, die ich für ein kleines bisschen gehabt habe, also wollte ich vorausgehen und fragen. So werde ich ein Beispiel in PHP geben:Vererbung unter der Haube

<?php 

class Base 
{ 
    private $z = 4; 


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

} 

class Derived extends Base 
{ 
} 

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

$d->GetPrivate(); 

>

Einfach genug. Wenn ich immer über Vererbung gelesen habe, war die Erklärung einfach nur "Sie erben die öffentlichen und geschützten Mitglieder" und das war's. Was ich nicht verstehe, sind ein paar Dinge darüber, wie der Dolmetscher in diesem Beispiel abbildet, was zu was gehört.

Zum Beispiel, wenn ich eine abgeleitete Klasse erstellen, kann ich die öffentliche Funktion "GetPrivate" der Base die privaten Variablen der Basisklasse erhalten. Die einfache Definition der Vererbung funktioniert mir damit jedoch nicht. Was ich meine ist, ich erhalte die GetPrivate-Methode, aber habe immer noch irgendeine Art von Link zu privaten Variablen nur von der Methode, die der Basisklasse gehörte (obwohl $ dies auf das abgeleitete Klassenobjekt bezieht). Ich konnte keine neue Funktion in der Abgeleiteten Klasse erstellen, um auf diese privaten Variablen zuzugreifen.

Behält der Interpreter also die geerbten Funktionen der Basisklasse und die möglichen Links zu privaten Mitgliedern im Auge, die nur für diese Basisklasse verfügbar sind?

Antwort

2

Der Interpreter (oder Compiler in einer anderen OOP-Sprache) prüft den Zugriff Schritt für Schritt.

Wenn Sie $d->GetPrivate(); rufen, überprüfen Sie die Dolmetscher den Kontext, in dieser Haupt (öffentlichen Kontext als ich davon ausgehen, dass Sie nicht in einer verwandten Klasse Drerived oder Base sind) und GetPrivate() ist eine öffentliche Methode. Somit ist $d->GetPrivate(); in diesem Zusammenhang also kein Fehler erlaubt.

In GetPrivate(), die Kontext-Objekt als $dBase und der Zugang zu z ist ein privates Element des aktuellen Objekts ($d). Somit ist der Zugriff gültig.

Das Konzept, das hier zum Einsatz kommt, ist 'Data Hiding' (Zugangskontrolle) und 'Encapsulation' (Kombination von Daten und Funktion).

Vererbung von nur zu spielen erlaubt GetPrivate() von Base verwendet werden, da es zu einem Objekt von Derived gehören.

Es ist wahr, dass es noch eine Verbindung zu einer privaten Daten gibt, aber diese Verbindung ist keine direkte. Die Wichtigkeit ist, dass der Zugriff geschieht als Base Klasse zulässig.

So Ihre Frage zu beantworten ist:

YES! Der Interpreter hält fest, welche geerbten Funktionen von der Basisklasse und welche Verbindungen sie zu privaten Mitgliedern haben, die nur für diese Basisklasse verfügbar sind.

Hoffe, das hilft.

2

Die Antwort ist ein einfaches Ja, versuchen Sie dies aus:

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

Sie, dass jetzt sehen, dass wir getPrivate auf der Derived Klasse definiert haben, können wir keinen Zugriff mehr z im Base seit seinem privaten, wenn wir wollen in der Lage sein, von der abgeleiteten Klasse auf sie zuzugreifen, müssen wir sie als geschützt anstatt als privat deklarieren.

1

Nun, ich kann nicht viel sagen über die Parser Details, aber der Schlüssel zum Verständnis ist, zu verstehen, was visibility bedeutet:

Klasse Mitglieder erklärten Öffentlichkeit überall zugegriffen werden kann. Auf Member, die als protected deklariert sind, kann nur innerhalb der Klasse selbst sowie durch geerbte und übergeordnete Klassen zugegriffen werden. Auf Mitglieder, die als privat deklariert sind, darf nur die Klasse zugreifen, die das Mitglied definiert hat.

Now, the PHP manual also states:

Zum Beispiel, wenn Sie eine Klasse erweitern, erbt die Unterklasse alle öffentlichen und geschützten Methoden der Elternklasse. Wenn eine Klasse diese Methoden nicht überschreibt, behalten sie ihre ursprüngliche Funktionalität bei.

Wenn Sie ein var_dump($d) auf der abgeleiteten Klasse zu tun, werden Sie sehen, es enthält Base->z:

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

So gibt es einen Verweis auf z in der Base, aber es ist privat und da private Mittel das Mitglied Auf die Klasse, die das Mitglied definiert, kann nur zugegriffen werden, von Abgeleitet kann nicht darauf zugegriffen werden.

Indem Sie eine öffentliche Methode in Base bereitstellen, um an das private Mitglied zu gelangen, steuern Sie den Zugriff effektiv über die übergeordnete Methode. Vielleicht ist $z etwas, das in erweiterten Klassen schreibgeschützt sein muss, beispielsweise ein Datenbankadapter.

Dies ist Informationsverbergung und Zugriffskontrolle. Es bedeutet nicht, dass Sie $ z verlieren, wenn Sie Base erweitern. Vererbung ist eine is-a Beziehung. Abgeleitet is-a Base und als solche hat es ein $ z, obwohl nicht auf sich selbst, sondern durch seine Eltern.

Verwandte Themen