Fórum Tela filha usando OOP e herança #372876

29/07/2009

0

Olá pessoal.

Vejo que um assunto que é de curiosidade de muitos e de conhecimento de poucos, OOP.

Quero tratar aqui um assunto relacionado a OOP, e quero discutir quais as maneira de se resolver alguns problemas.

Problema:
Tela Filha: bom tela filha para mim seria tela para cadastrar as filhas dos relacionamentos, por exemplo Pedido Venda Item, Nota Fiscal Item....
Fiz uma tela filha chamaremos de TXFilha, então todas as telas filhas que precisarei fazer no meu sistema hedaram de TXFilha.
Usando conceitos de OOP, quero que minha TXFilha, um objeto, tenha as suas proprias responsabilidades, por exemplo: Saber se criar, Saber se destruir.
Pq fazer isso?
Bem não gosto de toda hora que tiver que chamar uma tela filha eu tenho q ficar fazendo o seguinte codigo
PedidoVendaItem := TPedidoVendaItem.create(nil)
try
  PedidoVendaItem.ShowModal;
finally
  PedidoVendaItem.release;
  PedidoVendaItem := nil
end;

e sim gostaria de fazer o seguinte:
TPedidoVendaItem.Execute;


[b:aa59fd5616]Solução encontrada:[/b:aa59fd5616]
Fiz um metodos de classe (Class Method) no TXFilha
class function Execute:boolean;
begin
XFilha := TXFilha.create(nil)
try
  XFilha.ShowModal;
finally
  XFilha.release;
  XFilha:= nil
end;
end;


XD
Parece bom né, neh?
Mas nesse caso se não tivesse herança funcionaria certinho.
Infelizmente temos herança, e qdo eu fizer
TPedidoVendaItem.Execute;

Em vez dele instanciar o TPedidoVendaItem, ele instancia o proprio TXFilha.
Se for analisar o codigo... realmente era isso que deveria acontecer.
Pois no Execute no PedidoVendaItem que por herança executa o execute do XFilha, e la ele instancia o XFilha.

Quais as sugestões que vcs me dão para resolver isso?
Resolvi fazendo uns cast que vou postar aqui mais tarde. Pois não estou com o codigo aqui.

Obrigado.


Osocram

Osocram

Responder

Posts

29/07/2009

Et.vinny

Faça igual a OPP.
As suas telas filhas, você deve criar um Objeto que herde de um TForm, ou de um TForm já existente na sua aplicação.

Para fazer funcionar ela, você declara uma variavel do tipo do objeto selecionado, e faz um create, e dentro deste create você pode fazer show modal.

E por ai vai....

Acho que tenho um exemplo aqui...
Vou dar um procurada e ver se eu acho...
Senão faço ele de novo..

Atenciosamente

Marlon


Responder

Gostei + 0

29/07/2009

Osocram

Então Marlon.

O TXFilha é herdado do TForm.

Parece bem simples o prob. Se tiver um tempo faça ele na pratica p vc realmente ver o prob.

---------------------
Faça uma herança do TForm e crie o TXfilha
nele v coloca apenas um TPanel e muda o caption para ´Filha´
E crie o metodo Execute que nem eu passei

Dae crie um outro form ´TFiota´ herdando de TXFilha
Dae muda o caption do panel para ´Fiota´.

Até aqui tudo blz.
Agora no form principal chame o TFiota.execute;
Em vez de instanciar o TFiota vai instanciar o TFilha, vc vai saber disso por causa do caption do Panel
--------------------------------------------------
Faça igual a OPP. As suas telas filhas, você deve criar um Objeto que herde de um TForm, ou de um TForm já existente na sua aplicação. Para fazer funcionar ela, você declara uma variavel do tipo do objeto selecionado, e faz um create, e dentro deste create você pode fazer show modal. E por ai vai.... Acho que tenho um exemplo aqui... Vou dar um procurada e ver se eu acho... Senão faço ele de novo.. Atenciosamente Marlon



Responder

Gostei + 0

29/07/2009

Guinther

Isso acontece pois métodos de classe são estáticos e não polimórficos / virtuais. Você precisa usar o tipo em um método genérico, passando uma [b]referência de classe[b], algo como:

procedure TSuaClasseBase.Execute(InstanceClass: TComponentClass; var Reference);
var
Instance: TComponent;
begin
Instance := TComponent(InstanceClass.NewInstance);
TComponent(Reference) := Instance;
try
Instance.Create(Self);
except
TComponent(Reference) := nil;
raise;
end;
try
TForm(Reference).ShowModal;
finally
TForm(Reference).Release;
end;
end;

Para usar:

Execute(TForm2,Form2);

Att

Guinther Pauli
guintherpauli.blogspot.com
twitter.com/guintherpauli


Responder

Gostei + 0

29/07/2009

Osocram

Ola Guinther...
Vou testar isto que vc passou....

eu consegui resolver fazendo assim

class function TXTelaFilhaF.ChamaFilha(aClasse:string):boolean;
var
  vClass: TPersistentClass;
  vForm: TForm;
begin
  //qdo um MDIChild for criado enton sera automaticamente adicionado a esse menu
//  WindowMenu := mn_Janela;
  result := false;
  vClass := GetClass(aClasse);
  if vClass <> nil then begin
    vForm := TFormClass(vClass).Create(nil);
    try
      if vForm.ShowModal = mrOK then
        result := true;
    finally
      vForm.Release;
      vForm := nil;
    end;
  end;
end;


*** Aproveitar para dar os parabens pelo seu artigo neste ultima edição do Clube Delphi ´Introdução à POO´.

Flw.
Vlw.

Isso acontece pois métodos de classe são estáticos e não polimórficos / virtuais. Você precisa usar o tipo em um método genérico, passando uma [b]referência de classe[b], algo como: procedure TSuaClasseBase.Execute(InstanceClass: TComponentClass; var Reference); var Instance: TComponent; begin Instance := TComponent(InstanceClass.NewInstance); TComponent(Reference) := Instance; try Instance.Create(Self); except TComponent(Reference) := nil; raise; end; try TForm(Reference).ShowModal; finally TForm(Reference).Release; end; end; Para usar: Execute(TForm2,Form2); Att Guinther Pauli guintherpauli.blogspot.com twitter.com/guintherpauli



Responder

Gostei + 0

30/07/2009

Emerson Nascimento

[b:94836e0b28]osocram[/b:94836e0b28], acho que é mais simples do que se pensa....

testei com esse código e funcionou perfeitamente:
class function TXFilha.Execute: boolean;
var
  vForm: TForm;
begin
  result := false;
  vForm := Self.Create(nil);
  try
    if vForm.ShowModal = mrOK then
      result := true;
  finally
    vForm.Release;
    vForm := nil;
  end;
end;

as classes herdadas de TXFilha foram instanciadas corretamente, seguindo o exemplo que você passou.


Responder

Gostei + 0

30/07/2009

Osocram

Apesar de eu ja ter conseguido fazer funcionar... eu gostaria de continuar discutindo p entender melhor.

realmente funcionou este codigo q vc passou :shock:

 vForm := Self.Create(nil);

Essa parte do seu codigo eu nunca tinha tentado pois achei que não teria o Self ainda... pois eu não instanciei o objeto ainda.
Mas realmente funcionou
XD
Saberia explicar isso? Pelo menos foi assim que eu aprendi.

vou fazer outro teste aqui... fazendo um cast pois preciso inicializar uma variaveis neste metodo Execute.

Vlw a dica.

[b:fcbd7135e3]osocram[/b:fcbd7135e3], acho que é mais simples do que se pensa.... testei com esse código e funcionou perfeitamente:
class function TXFilha.Execute: boolean;
var
  vForm: TForm;
begin
  result := false;
  vForm := Self.Create(nil);
  try
    if vForm.ShowModal = mrOK then
      result := true;
  finally
    vForm.Release;
    vForm := nil;
  end;
end;
as classes herdadas de TXFilha foram instanciadas corretamente, seguindo o exemplo que você passou.



Responder

Gostei + 0

30/07/2009

Osocram

Fiz o teste ja.
[b:eaf2b85bb9]showmessage(TXTelaFilhaF(vForm).dsFilha.DataSet.name);[/b:eaf2b85bb9]
if vForm.ShowModal = mrOK then
result := true;

Adicionei este showMessage no... para mostrar o nome do dataset setado no DataSource, este DataSet so existe nos forms herdado , então ficou perfeito, melhor ainda do que eu ja tinha feito.

em vez de chamar assim
  TOpeLancamentoItemF.Execute(´TOpeLancamentoItemF´);

Agora posso chamar assim
TOpeLancamentoItemF.Execute;


Show de bola.
Brigadão Emerson.

*Se puder explicar a teoria do Self la no Class function eu agradeceria.


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar