Tela filha usando OOP e herança
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
e sim gostaria de fazer o seguinte:
[b:aa59fd5616]Solução encontrada:[/b:aa59fd5616]
Fiz um metodos de classe (Class Method) no TXFilha
XD
Parece bom né, neh?
Mas nesse caso se não tivesse herança funcionaria certinho.
Infelizmente temos herança, e qdo eu fizer
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.
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
Curtidas 0
Respostas
Et.vinny
29/07/2009
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
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
GOSTEI 0
Osocram
29/07/2009
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
--------------------------------------------------
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
GOSTEI 0
Guinther
29/07/2009
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
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
GOSTEI 0
Osocram
29/07/2009
Ola Guinther...
Vou testar isto que vc passou....
eu consegui resolver fazendo assim
*** Aproveitar para dar os parabens pelo seu artigo neste ultima edição do Clube Delphi ´Introdução à POO´.
Flw.
Vlw.
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
GOSTEI 0
Emerson Nascimento
29/07/2009
[b:94836e0b28]osocram[/b:94836e0b28], acho que é mais simples do que se pensa....
testei com esse código e funcionou perfeitamente:
as classes herdadas de TXFilha foram instanciadas corretamente, seguindo o exemplo que você passou.
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.
GOSTEI 0
Osocram
29/07/2009
Apesar de eu ja ter conseguido fazer funcionar... eu gostaria de continuar discutindo p entender melhor.
realmente funcionou este codigo q vc passou :shock:
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.
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:
as classes herdadas de TXFilha foram instanciadas corretamente, seguindo o exemplo que você passou.
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;
GOSTEI 0
Osocram
29/07/2009
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
Agora posso chamar assim
Show de bola.
Brigadão Emerson.
*Se puder explicar a teoria do Self la no Class function eu agradeceria.
[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.
GOSTEI 0