Ver Mensaje Individual
  #3  
Antiguo 22-04-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Reputación: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

A ver si nos entendemos.

Una clase es una clase, y un objeto es un objeto. Un objeto es la instancia de una clase. Una clase es como un molde de un objeto. No tienes que crear veinte clases (creo), sino que tienes que crear 20 objetos de una determinada clase.

¿Cómo se instancia una clase de objeto en Delphi? ¿Cómo se crean objetos de una clase? Mediante los constructores conque cada clase cuenta, que no son sino unos métodos "especiales" que inicializan variables, preparan un objeto, en fin, de una determinada clase.

Su contraparte está en los "destructores", que se utilizan para liberar memoria, por ejemplo, o para cualquier otra tarea que hubiera que llevar a cabo cuando se destruye un determinado objeto de cierta clase.

¿Pero cómo creas un objeto, demonios? Te estarás preguntando. No soy yo el más indicado para estar aquí ahora escribiendo esto, sin modestia lo digo, pero, en definitiva, tendrás que fijarte en el constructor o constructores (porque puede haber más de uno) de la clase en cuestión, para saber cómo tienes que tratar con ello.

¿Un ejemplo? De acuerdo. Creemos una instancia de la clase "TEdit", por ejemplo, que sabes que es un control visual de los que vienen en la pestaña "Standard" de la paleta de componentes de Delphi.

¿Dónde se encuentra definida la clase "TEdit"? En la unidad "StdCtrls" (de Standard Controls). Pues bien, lo primero sería requerir esa unidad, para poder trabajar con la clase "TEdit", ya sabes:

Código Delphi [-]
uses
  StdCtrls;

Ahora tendremos que buscarle un hogar a la instancia del objeto que queremos crear. Digamos que una variable del tipo de objeto que queremos crear nos puede venir bien. Así que declaremos una variable de ese tipo en donde sea... bueno, en donde sea que nos haga falta, por ejemplo, supongamos que vamos a utilizar un objeto "TEdit" que crearemos en tiempo de ejecución en un formulario:

Código Delphi [-]
unit Unit2;

interface

uses
  Forms, StdCtrls;

type
  TForm2 = class(TForm)
  private
    MiEdit: TEdit; // aquí estoy
  end;

var
  Form2: TForm2;
  MiEdit: TEdit; // o aquí también

implementation

{$R *.dfm}

var
  MiEdit: TEdit; // incluso aquí

end.

¿Ves la variable "MiEdit" declarada en la sección "private" de la clase "TForm2"? También ves cómo pudimos declararla fuera de la clase "TForm2", en la cláusula "interfaz" de la unidad que contiene el formulario, e incluso pudimos declararla en la cláusula "implementation".

Igualmente podríamos haberla declarado dentro de un procedimiento, función o método. Por ejemplo, imagina que dentro de la cláusula "implementation" de la unidad anterior tuviéramos algo así:

Código Delphi [-]
procedure TForm2.Button1Click(Sender: TObject);
var
  MiEdit: TEdit;
begin

end;

Estaríamos declarando una variable capaz de contener la referencia de un objeto de la clase "TEdit" dentro del método "Button1Click", en este caso.

Muy bien. ¿Pero cómo creo el objeto? Vamos a ello. Sigamos con la variable que declaramos en el método susomentado. Así creamos una instancia de la clase "TEdit":

Código Delphi [-]
procedure TForm2.Button1Click(Sender: TObject);
var
  MiEdit: TEdit;
begin
  MiEdit := TEdit.Create(Self);
  MiEdit.Parent := Self;


  MiEdit.Free;
end;

Vamos por líneas. Primero hacemos uso del constructor de la clase "TEdit", el cual nos pide como parámetro un componente "propietario" para el objeto "TEdit" que queremos crear. Nosotros le damos como padre el "Form2", es decir, como sabes, la variable "Self" contiene una referencia al objeto en cuyo método estamos trabajando, que en este caso es "Form2". El propietario del "TEdit" se encargará de liberar la memoria ocupada con este en su destrucción, en la del propietario mismo, aunque nosotros podemos encargarnos de esa tarea también por nuestra cuenta.

El objeto, a partir de ahí, está ya en memoria, vivito y coleando, pero, no le veríamos sino fuera por la siguiente línea. Este "TEdit" es muy suyo, y, como otros controles similares, además de un "propietario" nos solicita un "padre". Es como si nos preguntara, "está bien, aquí estoy, pero, ¿dónde quieres que me muestre?" Y nosotros le respondiéramos con las mismas, ¡en el mismo formulario, y deja ya de ser pesado y muéstrate ya!

Y el "TEdit" obediente se muestra... ¡pues no faltaba más!

Pero una instrucción más abajo, oh, amigo, la vida es así, destruimos el "TEdit", liberamos su memoria y adiós, ahí te pudras. Porque ya no nos hacía falta, naturalmente. De otro modo podríamos seguir usándolo hasta cuando hubiéramos querido.

¿Diferencias entre declarar la variable "TEdit" en la clase del formulario, en la cláusula "interface", en la cláusula "implementation" o en el procedimiento, como hemos hecho? Bueno. Eso para otra pregunta, que ya estoy viendo que me estoy enrollando demasiado con esta, y no sé yo hasta dónde vamos a llegar...

Pero... ¡casi se me olvida! ¡Tú querías crear veinte clases, digo objetos! ¡De una tacada! (?) ¡Y en tiempo de ejecución! ¡Vade retro! Bueno. Pues como casi con todo en esto de la programación, habrá varias formas de enfocar las cosas, y en parte tiene que ver qué pretendemos conseguir.

Si te explayas un poco más en lo que necesitas, tal vez alguien pueda ofrecerte más información. Yo te diría respondería que puedes crear un arreglo de los "TEdit" (seguimos con el ejemplo), o puedes utilizar una variable que contenga (o vaya conteniendo) los "TEdit" que necesites... no sé qué decirte, porque tampoco sé qué necesitas realmente.

Aquí te dejo algo de código escrito a vuela pluma, que seguramente contenga errores, pero tal vez pueda darte alguna idea. Se admiten sugerencias a todas horas de lunes a viernes y sábados y festivos que no sean de guardar.

Código Delphi [-]
uses
  Contnrs; // Contiene la clase TObjectList

var
  // Un array preparado para contener 20 TEdit
  FEditsA: array [0..19] of TEdit;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
begin
  Randomize;
  for i := 0 to High(FEditsA) do
  begin
    FEditsA[i] := TEdit.Create(Self);
    FEditsA[i].Parent := Self;
    FEditsA[i].SetBounds(Random(Self.Width-100),
      Random(Self.Height-20), 100, 20);
  end;
end;

var
  FEditsB: TObjectList;

procedure TForm1.Button2Click(Sender: TObject);
var
  nEdit: TEdit;
begin
  nEdit := TEdit.Create(Self);
  nEdit.Parent := Self;
  Randomize;
  nEdit.SetBounds(Random(Self.Width-100),
    Random(Self.Height-20), 100, 20);

  if not Assigned(FEditsB) then
    FEditsB := TObjectList.Create;

  FEditsB.Add(nEdit);

  ShowMessage(Format('Edits en FEditsB: %d', [FEditsB.Count]));
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FEditsB.Free;
end;

No comento el código porque creo que más o menos podrá entenderse, y porque ya me he cansado un poco de aporrear las teclas... pero puedes comentar lo que te parezca del mismo, que aquí estaremos en cuanto hayamos descansado un poco.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita