PDA

Ver la Versión Completa : Métodos de clase.


jplj
17-11-2004, 08:55:45
¿ 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
¿ 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
¿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 ;)

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.

..., 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.

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
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 ?

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; ...

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.


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:


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
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:


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.


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):



j:= TForm2.Suma(5,4);

roman
18-11-2004, 15:26:16
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
...
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
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
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