Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Métodos de clase. (https://www.clubdelphi.com/foros/showthread.php?t=16126)

jplj 17-11-2004 08:55:45

Métodos de clase.
 
¿ Es posible llamar a un método de clase dentro de la misma clase que lo define ?.

Saludos.

Neftali [Germán.Estévez] 17-11-2004 11:01:05

Cita:

Empezado por jplj
¿ Es posible llamar a un método de clase dentro de la misma clase que lo define ?.

En la ayuda de Delphi aparece lo siguiente:

A class method can be called through a class reference or an object reference. When it is called through an object reference, the class of the object becomes the value of Self.

Por lo tanto, entiendo que sí se puede llamar desde una instancia de una clase (la misma que lo define). Otra cosa es, para qué puedes necesitar una cosa así que no me lo imagino, pero poder creo que se puede.
No lo he probado nunca, sólo es una apreciacióonm de lo que leo en la ayuda, para estar 100% seguro habría que intentarlo.

jplj 17-11-2004 12:45:20

¿Para qué lo quiero hacer?: para hacer una ¿"chapuza"?.

Pretendo poder llamar a los métodos de clase desde diveros puntos de la apliación sin necesidad de instanciar la clase, pero resulta que en la propia clase es necesario el método que se define como método de clase.

Lo adecuado, creo, sería llevar la función que defino como método de clase a otra unit, para poder compartila. Pero quería probar este enfoque.

Saludos.
Juan P.

Neftali [Germán.Estévez] 17-11-2004 13:19:15

Crea un método A (de clase) y otro B; El método de clase A lo único que debe tener dentro es la llamada a B; Para llamarlo desde Dentro puedes utilizar B, para llamarlo desde fuera puedes utilizar A; De todas maneras no acabo de verlo claro... tal vez estoy "espesito" hoy;) .

andres1569 17-11-2004 13:21:38

Cita:

Empezado por jplj
¿Para qué lo quiero hacer?: para hacer una ¿"chapuza"?.

Bueno, no es algo tan raro, sino más bien normal, no creo que estés haciendo ninguna chapuza por ello ;)

Cita:

Empezado por jplj
Pretendo poder llamar a los métodos de clase desde diveros puntos de la apliación sin necesidad de instanciar la clase

Ésa es la principal ventaja y finalidad de dichos métodos, la no necesidad de tener creada una instancia.

Cita:

Empezado por jplj
..., pero resulta que en la propia clase es necesario el método que se define como método de clase.

Tengo clases y componentes donde esta práctica es habitual. Lo prohibitivo es llamar a métodos no de clase desde un método de clase, o el uso de variables internas a la clase, pues ello requeriría necesariamente que dichas variables existieran en memoria (tener creada una instancia de la misma) lo cual choca con su razón de ser.

Cita:

Empezado por jplj
Lo adecuado, creo, sería llevar la función que defino como método de clase a otra unit, para poder compartila. Pero quería probar este enfoque.

No entiendo esto, un método de clase, como cualquier método, se supone que es parte integrante de una clase y le pertenece por algo, no veo que haya que crear una "función suelta" para ello. Aunque depende de lo que quieras hacer exactamente, pero eso seguramente es otro tema ...

Saludos.

jplj 17-11-2004 14:33:27

Cita:

Empezado por andres1569
Lo prohibitivo es llamar a métodos no de clase desde un método de clase, o el uso de variables internas a la clase, pues ello requeriría necesariamente que dichas variables existieran en memoria (tener creada una instancia de la misma) lo cual choca con su razón de ser.

Luego entiendo que lo que dice Neftali no es correcto ?

Cita:

Empezado por Neftali
Crea un método A (de clase) y otro B; El método de clase A lo único que debe tener dentro es la llamada a B; Para llamarlo desde Dentro puedes utilizar B, para llamarlo desde fuera puedes utilizar A; ...

Cita:

Empezado por andres1569
No entiendo esto, un método de clase, como cualquier método, se supone que es parte integrante de una clase y le pertenece por algo, no veo que haya que crear una "función suelta" para ello. Aunque depende de lo que quieras hacer exactamente, pero eso seguramente es otro tema ...

Es otro tema ... , en el que por cierto me he metido yo solito (por leer cosas que no debo).
Así es que si no me funciona lo dejo como está y andando.

Saludos.

Neftali [Germán.Estévez] 17-11-2004 16:11:33

No acabo de entender qué significa ésta frase:
"...Lo prohibitivo es llamar a métodos no de clase desde un método de clase"

Se puede llamar desde un método definido como class (método de clase) a otros metodos de la misma clase (public o published -incluso privates y protected, aunque no sea recoimendable-) que no estén definidos como métodos de clase (con class); Eso no tiene ningun problema; Revisa el siguiente código:

NOTA: Corresponde a un formulario que utiliza un método de clase para crear e inicializarse.

Código Delphi [-]
unit Unit2_classMethod;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
type
  TForm2 = class(TForm)
  private
    procedure LeerDisco;
    { Private declarations }
  public
    { Public declarations }
    procedure Inicializar;
  published
    class procedure Crear();
  end;
var
  Form2: TForm2;
implementation
{$R *.dfm}
{ TForm2 }
class procedure TForm2.Crear;
var
  F:TForm2;
begin
  // Crear el objeto
  F := TForm2.Create(nil);
  // Bloque de proteccion
  try
    // Llamar a "Método no de clase"
    F.Inicializar;
    // Llamar a "Método no de clase" que además está PRIVATE; 
    // Lo permite porque está en la misma Unit 
    // (entiendo que no se debería utilizar)
    F.LeerDisco;
    // show 
    F.ShowModal;
  finally
    F.Free;
  end;
end;
 
procedure TForm2.LeerDisco();
begin
  MessageDlg('Leyendo de disco...', mtInformation, [mbOK], 0);
end;

procedure TForm2.Inicializar();
begin
  MessageDlg('Inicializando...', mtInformation, [mbOK], 0);
end;
end.

Para llamarlo utilizarías:

Código Delphi [-]
  TForm2.Crear();

...tal vez no he entendido bien la cuestión, si es así pido discupas;

P.D: A ésto me refería con crear un método de clase que llama a otros métodos no de clase, de forma que desde fuera se puede llamar a Crear, y desde dentro se puede llamar a Inicializar y LeerDisco.

andres1569 17-11-2004 18:09:34

Cita:

Empezado por Neftali
No acabo de entender qué significa ésta frase:
"...Lo prohibitivo es llamar a métodos no de clase desde un método de clase"

Me refiero a llamadas directas a métodos no de clase, es decir sin mediar ninguna instancia de por medio; en el ejemplo que pones es perfectamente legal puesto que creas una variable local F y llamas a algunos de sus métodos, pero en dicho caso puedes llamar a dichos métodos, sean de clase o no, porque los llamas a través de una instancia de la clase (F).

El ámbito (private, protected, public ... etc), tal como dices, no importa en este asunto, es algo colateral.

A todo esto, los constructores son por naturaleza métodos de clase, la misma forma en que creamos objetos así lo indica:

MiObjeto := TMiObjeto.Create; // se comporta como un método de clase

por lo que dentro de un método de clase se puede llamar perfectamente a Create o a cualquier otro constructor.

Lo que sería ilegal es incluir dentro de ese método de clase una llamada directa a un método no de clase, siguiendo tu ejemplo:

Código Delphi [-]
class procedure TForm2.Crear;
var
  F:TForm2;
begin
  F := TForm2.Create(nil);
  F.Inicializar;   // correcto, accedemos a través de una instancia
  Inicializar;  // incorrecto; es una llamada directa
  F.Free;
end;

La inclusión de una llamada directa a un método no de clase aquí genera el siguiente error en Delphi:

"This form of method call only allowed for class methods".

Espero haberme explicado ahora mejor,

Saludos

jplj 18-11-2004 14:20:06

Parte de mi pregunta era si dentro de la propia clase se puede llamar a un método de clase de ella.

Código Delphi [-]
unit Unit2_classMethod;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
type
  TForm2 = class(TForm)
  private
    procedure LeerDisco;
    { Private declarations }
  public
    { Public declarations }
    procedure Inicializar;
  published
    class procedure Crear();
    class function Suma(x, y: integer): Integer;  
end;
var
  Form2: TForm2;
implementation
{$R *.dfm}
{ TForm2 }

class function Suma(x, y: integer): Integer;
begin
   result:= x+y;
end;

class procedure TForm2.Crear;
var
  F:TForm2;
begin
  // Crear el objeto
  F := TForm2.Create(nil);
  // Bloque de proteccion
  try
    // Llamar a "Método no de clase"
    F.Inicializar;
    // Llamar a "Método no de clase" que además está PRIVATE; 
    // Lo permite porque está en la misma Unit 
    // (entiendo que no se debería utilizar)
    F.LeerDisco;
    // show 
    F.ShowModal;
  finally
    F.Free;
  end;
end;
 
procedure TForm2.LeerDisco();
begin
  MessageDlg('Leyendo de disco... La suma es: ' + IntToStr(Suma(4,5)),    mtInformation, [mbOK], 0);  
end;

procedure TForm2.Inicializar();
begin
  MessageDlg('Inicializando...', mtInformation, [mbOK], 0);
end;
end.

Y luego desde otro punto de la apliación (otra unit):

Código Delphi [-]
    
    j:= TForm2.Suma(5,4);

roman 18-11-2004 15:26:16

Cita:

Empezado por jplj
Parte de mi pregunta era si dentro de la propia clase se puede llamar a un método de clase de ella

Claro que sí. Me parece que ya Andrés lo ha dejado muy claro:

Métodos regulares pueden llamar directamente a métodos de clase.
Métodos de clase pueden llamar directamente a métodos de clase.
Métodos de clase no pueden llamar directamente a métodos regulares.

Lo que haces en Form2.Crear es correcto ya que estás llamando desde un método de clase, métodos regulares de una instancia de la clase.

Lo incorrecto sería que Form2.Crear llamara directamente a TForm2.Inicializar sin crear una instancia de por medio.

// Saludos

andres1569 18-11-2004 19:25:50

Cita:

Empezado por roman
...
Métodos regulares pueden llamar directamente a métodos de clase.
Métodos de clase pueden llamar directamente a métodos de clase.
Métodos de clase no pueden llamar directamente a métodos regulares.

Me adhiero a esa terminología, métodos regulares en vez de métodos no de clase.

Jplj: En cuanto al método Suma no acabo de ver la utilidad ni la necesidad de implementarlo como método de una clase (aquí TForm2) y no como función suelta, basta con que lo metas en una unit general a toda tu aplicación (una unit que luego referencies en la cláusula Uses de aquellas units donde quieras usarla).

Saludos

jplj 19-11-2004 08:33:19

Muchas gracias por vuestras aclaraciones.

PD: Andrés, lo de la suma es sólo un ejemplo.

Saludos.

roman 19-11-2004 16:50:39

Cita:

Empezado por jplj
lo de la suma es sólo un ejemplo

Si te es posible, ¿nos podrías dar un ejemplo un poco más concreto del uso que vas a hacer de los métodos de clase? Siempre es bueno ver en qué se utilizan este tipo de técnicas.

// Saludos

mauriciofox 21-11-2004 17:07:32

CReo que este lio tiene nombre de recursividad
 
Si quiere le mando un componente que lo tiene hecho dice como parametro la clase y ya.

Pero si no me equivoco , creo que los linguajes de programacion lo tienen en su compilador . no tienes que hacer nada solamente de la clase A dentro ponerle la clase A ya definida.(logicamnete este no deve ser el unico codigo, porque quedaria un ciclo sin fin, )

yo lo hice para tener la satisfaccion de ke podia hacerlo. pero el compilador solo te lo hace.

Disculpa si tengo falta de ortografia
es que soy ukraniano

jplj 22-11-2004 09:30:19

En estos momento estoy "actualizando" una aplicación en la que se mantienen durante todo su funcionamiento varias instancias de diferentes clases con el único objetivo de proporcionar acceso a determinadas funciones que implementan. Creo que estas funciones pueden ser candidatas a convertirse en métodos de clase. Aunque también habría que sopesar si realmente son parte inherente de la clase tal como apunta Andrés.
Si finalmente me decido ha hacer el cambio, incluiré en este hilo un ejemplo.

PD.: También hay que pensar en el factor t . Esto lo quieren como regalo de Reyes.

Saludos


La franja horaria es GMT +2. Ahora son las 07:57:36.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi