2010-08-20 20 views
6

Por lo tanto, esta es la última pregunta persistente sobre la herencia que he tenido durante un tiempo, así que quería seguir adelante y preguntar. Así que voy a dar un ejemplo en PHP:?Herencia bajo el capó

<?php 

class Base 
{ 
    private $z = 4; 


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

} 

class Derived extends Base 
{ 
} 

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

$d->GetPrivate(); 

>

lo suficientemente simple. Cuando siempre leí acerca de la herencia, la explicación fue simplemente "heredas a los miembros públicos y protegidos" y eso es todo. Lo que no entiendo es un par de cosas sobre cómo el intérprete en este ejemplo calcula qué pertenece a qué.

Por ejemplo, cuando creo una clase derivada, puedo usar la función pública "GetPrivate" de la Base para obtener las variables privadas de la clase base. Sin embargo, la definición simple de herencia no funciona con esto para mí. Lo que quiero decir es que heredo el método GetPrivate pero todavía tengo algún tipo de enlace a variables privadas solo desde ese método que pertenecía a la clase base (aunque $ this se refiere al objeto de clase derivado). No pude crear una nueva función en la clase Derivada para acceder a esas variables privadas.

Por lo tanto, ¿el intérprete controla las funciones heredadas de la clase base y los posibles vínculos que mantienen a los miembros privados solo disponibles para esa clase base?

Respuesta

2

El intérprete (o compilador en otro lenguaje OOP), verifica el acceso paso a paso.

Cuando se llama a $d->GetPrivate();, el intérprete comprobar el contexto en el que es principal (contexto público como supongo que usted no está en una clase relacionada a Drerived o Base) y GetPrivate() es un método público. Por lo tanto, $d->GetPrivate(); está permitido en este contexto, por lo que no hay error.

En GetPrivate(), el contexto es $d objeto como Base y el acceso a z es un elemento privado del objeto actual ($d). Por lo tanto, el acceso es válido.

El concepto que entra aquí es 'Data Hiding' (control de acceso) y 'Encapsulation' (combinación de datos y función).

Herencia de para jugar solo permite GetPrivate() de Base para ser utilizado ya que pertenece a un objeto de Derived.

Es cierto que todavía hay un enlace a un Datos privados, pero ese enlace no es directo. La importancia es que el acceso ocurre como Base clase permitida.

Así que para responder a su pregunta es:

SÍ! El intérprete controla las funciones heredadas de la clase base y los posibles vínculos que mantienen con los miembros privados que solo están disponibles para esa clase base.

Espero que esto ayude.

2

La respuesta es un simple sí, pruebe esto:

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

verá que ahora que hemos definido getPrivate en la clase Derived que no puedan acceder z en el Base desde su privado, si queremos poder acceder a ella desde la clase derivada que necesitamos declarar que esté protegida en lugar de privada.

1

Bueno, no puedo decir mucho acerca de los detalles del analizador, pero la clave para la comprensión es en la comprensión de lo que significa visibility:

miembros de la Clase declararon pública se puede acceder a todas partes. Se puede acceder a los miembros declarados protegidos solo dentro de la clase en sí y por las clases heredadas y principales. Los miembros declarados como privados solo pueden acceder a la clase que definió al miembro.

Now, the PHP manual also states:

Por ejemplo, cuando extiende una clase, la subclase hereda todos los métodos públicos y protegidos de la clase padre. A menos que una clase anule esos métodos, conservarán su funcionalidad original.

Si lo hace un var_dump($d) en la clase derivada, verá que contiene Base->z:

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

Así que hay una referencia a la Z de la base, pero es privado y desde los medios privados del miembro solo se puede acceder por la clase que define al miembro, no se puede acceder desde Derivado.

Al ofrecer métodos públicos en Base para llegar al miembro privado, está controlando efectivamente el acceso a través del método principal. Tal vez $z es algo que tiene que ser de solo lectura en clases ampliadas, por ejemplo, un adaptador de base de datos.

Esta es la ocultación de la información y el control de acceso. No significa, si extiendes Base, perderás $ z. La herencia es una relación is-a. Derivado es-a Base y, como tal, tiene $ z, aunque no en sí mismo sino a través de su padre.

Cuestiones relacionadas