Algunas ventajas… (¡si eres capaz de recordarlas!) – Parte II

mayo 1, 2008 en Artículos, ¿Sabías que...?, ¿Sabías que...? [Delphi], Consejo, Delphi, Enlace interesante, Entrada Diario

Seguimos nuestro camino, persiguiendo la estela de cambios que nos proponía el enlace de la entrada anterior, pero sin abandonar la perspectiva que nos acompañaba en la parte I.

Hablabamos de ámbito y lo hacíamos fijandonos desde nuestro módulo de código hacia el exterior. Pero… es interesante fijar nuestra vista hacia el interior del mismo para descubrir que por fin, tras muchos años de subsistencia de un ambito de visibilidad que no nos permitía ocultar las declaraciones privadas de cada clase dentro del mismo módulo de datos, nos ha llegado un especificador de ambito que subsana el “problema”… Esto no es propio de 2007 pues ya es incorporado en las versiones anteriores pero quizás porque ambas han pasado con mas penas que gloria, es por lo que muchos puedan apercibirse de ello con los primeros pasos en el entorno de Delphi 2007. Creo recordar que en terminos coloquiales se hablaba de clases “amigas”. Ahora amistad es una cosa y confianza otra… :-) ¡Gracias a Dios!

El especificador de ambito restrictivo (strict) modifica tanto a private como a protected para que realmente la declaraciones hechas en los respectivos ambitos se oculten. En el caso de strict protected, se entiende perfectamente que solo va a poder ser visible las declaraciones de ese ámbito en una clase descendiente. Sin embargo, parece acertado que se haya mantenido la compatibilidad hacia atras permitiendo que private y protected sigan manteniendo el mismo comportamiento, lo cual hasta cierto punto es bastante razonable… ¡lo contrario hubiera sido un disparate! :-)

Pero lo mejor es poder verlo con un par de lineas de codigo que no van a compilar, precisamente porque vamos a violar expresamente un campo calificado como strict private desde el formulario.

unit uMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  THolaMundo1 = class
  private
    fSaludo: String;
  public
    procedure Saludar;
  end;

  THolaMundo2 = class
  strict private
    fSaludo: String;
  public
    procedure Saludar;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  f: THolaMundo1;
begin
   f:= THolaMundo1.Create;
   try
      f.fSaludo:= 'Hola Mundo';  //[private] podemos acceder
      f.Saludar;
   finally
        f.Free;
   end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  f: THolaMundo2;
begin
   f:= THolaMundo2.Create;
   try
      f.fSaludo:= 'Hola Mundo';  //[strict private] no podemos acceder a fSaludo
      f.Saludar;
   finally
        f.Free;
   end;
end;

{ THolaMundo2 }

procedure THolaMundo2.Saludar;
begin
   ShowMessage(fSaludo);
end;

{ THolaMundo1 }

procedure THolaMundo1.Saludar;
begin
   ShowMessage(fSaludo);
end;

end.

El error que nos genera es: “Cannot access private symbol “THolaMundo2.Saludo”.

De todas formas, cualquier programador, con independencia de haber aplicado la restricción de ambito, hubiera seguido las directrices de ocultación que nos marca la lógica de la programacion orientada a objetos y no violaría el acceso a los campos desde métodos o asignaciones directas que no fueran establecidas desde la parte publicada de la clase, que es para nosotros un contrato a cumplir. Eso nos dice la lógica…Luego cada uno, haga de su capa un sayo…
:-)