2012-02-22 9 views
7

En una clase base, existe un procedimiento protegido. Al heredar esa clase, quiero ocultar que ese procedimiento no se use desde el exterior. Traté de sobreescribirlo desde las privadas e incluso secciones privadas estrictas, pero todavía se puede llamar desde el exterior. La clase Original no es mía, así que no puedo cambiar cómo se define TOriginal.¿Cómo ocultar un procedimiento protegido de un objeto?

¿Es posible ocultar este procedimiento en mi clase heredada? ¿Y cómo?

type 
    TOriginal = class(TObject) 
    protected 
    procedure SomeProc; 
    end; 

    TNew = class(TOriginal) 
    strict private 
    procedure SomeProc; override; 
    end; 
+2

si desea ocultar método de clase base de la clase descendiente entonces usted tiene que declarar en sección privada; los métodos privados son visibles solo desde la clase propia; Los métodos protegidos son visibles desde la clase itslef y las clases heredadas y, finalmente, los métodos públicos o publicados son visibles para todos; publicado es lo mismo que public, pero esta sección es utilizada por delphi IDE para hacer visibles las propiedades de los componentes en el inspector de objetos; – teran

+0

también hay dos términos "ocultar" y "anular"; en su ejemplo, debe marcar 'SameProc' en la clase base como' virtual'; y luego redeclararlo en clase heredada y marcarlo como 'anular' significa anular; esto significa que si crea 'TNew' y asigna su instancia a la variable' TOriginal' ('var orig: = TNew.Create()') y luego de esa llamada a orig.SomeProc, se llamará a la implementación de TNew.SomeProc; si no lo marca como 'anulación', entonces orig.SomeProc es igual a 'TOriginal.SomeProc' también es inútil bajar la visibilidad del método porque siempre puede subirlo y llamar al – teran

+2

¿Qué es el código de detención utilizando su clase derivada de las referencias de conversión a referencias de la clase base o asignándolos? ¿Obtener acceso a cualquier método "oculto"? Lo que quieres no se puede hacer. Si sientes la necesidad de hacerlo, entonces las relaciones de herencia son todas incorrectas. – mghie

Respuesta

11

métodos protegidas son ya oculta desde el exterior. (En su mayoría; consulte más abajo.) No puede reducir la visibilidad de un miembro de la clase. Si la clase base declaró el método protegido, todos los descendientes de esa clase pueden usar el método.


En Delphi, otro tipo de código dentro de la misma unidad como clase pueden tener acceso los miembros protegidos de esa clase, incluso el código de clases no relacionadas. Eso puede ser útil a veces, pero generalmente para evitar otras deficiencias de diseño. Si tiene algo que "realmente, realmente" se supone que está protegido, puede hacerlo estricto protegido, y luego la regla de acceso a la misma unidad especial no se aplica.

+0

Y usando 'Class Helpers' todavía es posible acceder a miembros estrictamente protegidos/privados. –

+0

@LURD, mientras no haya 'ayudantes de unidad 'no hay posibilidad de acceder a miembros privados – OnTheFly

+0

La clase original (' TOriginal') no es mi clase, así que no puedo simplemente cambiarla. Mirando más adentro de la clase original, veo que 'SomeProc' es en realidad * public * más arriba en la familia, pero esta clase que estoy heredando lo ha movido a 'protected', lo que explica por qué puedo acceder a él entonces . Entonces, una vez que algo ha sido expuesto, no puede ser no expuesto? –

1

Una vez expuesto no se puede ocultar, pero se puede hacer esto al lugar donde se le llama en modo alguno limitar

TOriginalClass = class 
public 
    procedure Foo; 
end; 

TNewClass = class(TOriginalClass) 
public 
    procedure Foo; reintroduce; 
end; 

implementation 

procedure TNewClass.Foo; 
begin 
    Assert(False, 'Do not call Foo from this class'); 
    inherited Foo; 
end; 

var Obj: TNewClass; 
Obj := TNewClass.Create; 
Obj.Foo; // get assert message 

Will not get Assert error if declared as TOriginalClass 
var Obj: TOriginalClass; 
Obj := TNewClass.Create; 
Obj.Foo; // Never get the assert message 
+0

Gracias por la respuesta, y estoy algo comprensivo, pero no entiendo de dónde viene la sintaxis tipo C ... Esto no se parece al código Delphi puro ... –

+0

Si bien entiendo el punto, el código sigue siendo un poco sospechoso, principalmente ambas clases tienen 'Foo' en * público *? –

Cuestiones relacionadas