Me he encontrado con lo que creo que es un Bug en Delphi 2007, digo creo porque no estoy del todo seguro y espero ustedes me puedan ayudar a entender el porque.
Estoy creando un par de plantillas para mis desarrollos personales, y me dije: "Ya que estoy haciendo esto nuevo, ¿Porque no usar las nuevas características de mi Delphi?" .
Observen este código:
unit Unit6; interface type THola = class sealed(TObject) strict private FHola : Integer; Strict protected Function GetHola : Integer; property Hola : Integer read GetHola; public constructor Create(const AHOla : Integer); end; implementation { THola } constructor THola.Create(const AHOla: Integer); begin FHola := AHOla; end; function THola.GetHola: Integer; begin Result := FHola; end; end.
Hasta aquí todo bien, compila maravillosamente, aprovecho para recordar la definición de las palabras reservadas que he utilizado:
strict private: The private keyword actually creates a " friendship" relationship between classes in the same unit. The strict private declaration creates a true private field, not viewable by any other class, not even classes in the same unit.
strict protected: Similar to the strict private declaration, strict protected creates a true protected member, visible only to the declaring class and its descendents.
class sealed: Classes marked as sealed cannot be inherited from.
delphi
type TAbstractClass = class sealed procedure SomeProcedure; end;
Para tener mayor flexibilidad (desde mi punto de vista), decidí utilizar interfaces y realice lo siguiente:
unit Unit7; interface type IDefault = interface(IInterface) ['{66CA72EE-98FD-4DA5-9C07-59805D65E5F7}'] function GetNewProperty: Integer; property NewProperty: Integer read GetNewProperty; end; implementation end.
Ahora realizo la implementación de la interface:
unit Unit8; interface uses Unit7; type TDefault = class sealed(TInterfacedObject, IDefault) strict private FNewProperty : Integer; strict protected function GetNewProperty: Integer; property NewProperty: Integer read GetNewProperty; public constructor Create(const ANewProperty : Integer); end; implementation { TDefault } constructor TDefault.Create(const ANewProperty: Integer); begin FNewProperty := ANewProperty; end; function TDefault.GetNewProperty : Integer; begin Result := FNewProperty; end; end.
Pues, ¿Qué creen?. Mi querido Delphi me da error diciéndome: [DCC Error] Unit8.pas(22): E2003 Undeclared identifier: 'GetNewProperty' . Error del que no entiendo la lógica.
Si movemos el método y la propiedad a strict private, salta el mismo error; ahora bien si, ponemos nuevamente dichos métodos a strict protected y eliminamos la sentencia strict y dejamos protected, entonces si compila.
Se sobre entiende que al utilizar interfaces todos los métodos son públicos sin importar la visibilidad de donde se implemento, si se accede desde una variable tipo interface.
El siguiente código lo hago con la intención de mostrar lo que acabo de decir, no necesariamente deba de compilar:
type IDefault = interface(IInterface) ['{66CA72EE-98FD-4DA5-9C07-59805D65E5F7}'] function GetNewProperty: Integer; property NewProperty: Integer read GetNewProperty; end; TDefault = class (TInterfacedObject, IDefault) private FNewProperty : Integer; protected function GetNewProperty: Integer; property NewProperty: Integer read GetNewProperty; public constructor Create(const ANewProperty : Integer); end; TForm1.Button1Click(Sender : TObject); var X : IDefault; begin X := TDefault.Create(1); ShowMessage(IntToStr(X.GetNewProperty)); ShowMessage(IntToStr(X.NewProperty)); end;
Como ven, el código anterior accede a los métodos sin importar la visibilidad donde fueron implementados.
Espero haber sido lo bastante claro, ojala y puedan echarme una mano para tratar de entender el porque de ese error.