Você não está sendo chato e Orientação a Objetos é algo que gosto 
muito de discutir. Gostaria que outros participassem, mas...

Vamos lá!!!

Ainda não tive como testar, mas continuo achando que o typecast não 
é necessário porque você já criou um objeto do mesmo tipo para 
receber o objeto recuperado na lista.

Vejamos o problema da incubadora. Ao meu entender seria algo assim:

Type
  TEspecie = (tpPeixe, tpAnfibio, tpReptil, tpAve);


Type
  TAnimal = Class(TObject)
  Private
    FCodigo : Integer;
    FNome   : String;
    FEspecie: TEspecie;
  Protected
  Public
    Property Codigo : Integer  Read FCodigo;
    Property Nome   : String   Read FNome    Write FNome
    Property Especie: TEspecie Read FEspecie Write FEspecie;

    Function Listar(oEspecie: TEspecie): TList;
  End;


Type
  TOvo = Class(TObject)
  Private
    FCodigo: Integer;
    FAnimal: TAnimal;
    ...
  Protected
  Public
    Property Codigo : Integer Read FCodigo;
    Property Animal : TAnimal Read FAnimal Write FAnimal;
  End;


Type
  TIncubadora = Class(TObject)
  Private
    FCodigo      : Integer;
    FCapacidade  : Integer;
    FPrateleiras : Smallint;
    FTemperatura : Float;
  Protected
  Public
    Property Codigo     : Integer  Read FCodigo;
    Property Capacidade : Integer  Read FCapacidade  Write 
FCapacidade;
    Property Prateleiras: Smallint Read FPrateleiras Write 
FPrateleiras;
    Property Temperatura: Float    Read FTemperatura Write 
FTemperatura;

    Class Function ListaOvos: TList;
  End;

Se para você é importante saber em que local o Ovo está sem ter que 
perguntar e percorrer a emcubadora, monte um novo objeto para te 
auxiliar nessa tarefa, mas não acho que você deve criar uma 
referência da emcubadora no ovo.

Ex.:

Type
  TEstocagem = Class(TObject)
  Private
    FOvo        : TOvo;
    FEmcubadora : TEmcubadora;
    FPrateleira : Smallint;
    FPosicao    : Smallint;
  Protected
  Public
    Property Ovo       : TOvo        Read FOvo        Write FOvo;
    Property Emcubadora: TEmcubadora Read FEmcubadora Write 
FEmcubadora;
    Property Prateleira: Smallint    Read FPrateleira Write 
FPrateleira;
    Property Posicao   : Smallint    Read FPosicao    Write FPosicao;

    Function Buscar(oOvo: TOvo): Boolean; Overload;
  End;


O exemplo que você informou de um relacionamento 1 para 1 na verdade 
é um relacionamento 1 para N, porque um ovo só pode vir de uma 
avestruz, mas um avestruz pode pôr vários ovos. Estou certo?

Vamos colocar um relacionamento de 1 para 1 como sendo o de Pessoa e 
CNH (Carteira Nacional de Habilitação). Digamos que a Classe Pessoa 
terá um objeto do tipo TCNH junto aos seus atributos. Vejamos o 
exemplo:

Type
  TPessoa = Class(TObject)
  Private
    FCodigo: Integer;
    FNome  : String;
    FCNH   : TCNH;
  Protected
  Public
    Property Codigo : Integer Read FCodigo;
    Property Nome   : String  Read FNome  Write FNome;
    Property CNH    : TCNH    Read FCNH   Write FCNH;
  End;


Type
  TCNH = Class(TObject)
  Private
    FCodigo    : Integer;
    FNumero    : String;
    FRegistro  : String
    FCategoria : String;
    FDataExame : TDateTime;
    FExpedicao : TDateTime;
    FValidade  : TDateTime;
    FObservacao: String;
  Protected
  Public
    Property Codigo    : Integer   Read FCodigo;
    Property Numero    : String    Read FNumero     Write FNumero;
    Property Registro  : String    Read FRegistro   Write FRegistro;
    Property Categoria : String    Read FCategoria  Write FCategoria;
    Property DataExame : TDateTime Read FDataExame  Write FDataExame;
    Property Expedicao : TDateTime Read FExpedicao  Write FExpedicao;
    Property Validade  : TDateTime Read FValidade   Write FValidade;
    Property Observacao: String    Read FObservacao Write 
FObservacao;

    Function Buscar(iCodigo: Integer): Boolean; Overload;
    Function Buscar(sNumero: String): Boolean; Overload;
    Function Buscar(dtValidade: TDateTime): Boolean; Overload;
  End;

No exemplo acima sabemos que o objeto Pessoa conhece sua CNH através 
da instância do objeto que ele possui, mas se precisarmos conhecer 
uma Pessoa através de uma CNH o problema fica mais difícil. A 
solução que vejo no momento seria:

No seu DataModule:

Function TdmPessoa.Buscar(iCodigo: Integer, oPessoa: TPessoa): 
Boolean;
Begin

  With cdsPessoa Do
  Begin
    Try
      Close;
      CommandText := 'Select * From Pessoa P ' +
                     'Join CNH C On (P.Codigo = C.CodPessoa) ' +
                     'Where P.Codigo = ' + IntTostr(iCodigo);
      Open;

      If RecordCount > 0 Then
      Begin
        Result := True;
        Pessoa.Nome := FieldByName('Nome').AsString;
        ...
        Pessoa.oCNH.Buscar(iCodigo);
      End;
    Except
      on E: Exception do
      ShowMessage(E.Message);
    End;
  End;
End;


Ufa!!! Acho que exemplifiquei bastante dessa vez. Vai dar até para 
escrever um livro. :-D

Obs.: Como estou codificando direto no corpo do e-mail, pode ser que 
aja alguns erros. :-(

Sds,

Romario





--- Em delphi-br@yahoogrupos.com.br, Francisco Trindade 
<[EMAIL PROTECTED]> escreveu
>  O typecast é necessario na medida em que vc deseja acessar 
propriedades
> especificas do endereco, mas estou comecando a concordar que o 
risco e baixo
> quanto aos erros.
>  Quanto a dupla navegabilidade, neste exemplo realmente nao existe
> necessidade, mas por exemplo, um caso que tenho é o de uma 
incubadora de
> ovos de avestruzes.
>  Ela tem uma lista de ovos, que sao os quais estao armazenados 
nela. Mas em
> varios pontos do programa, seria util eu descobrir onde o ovo esta
> armazenado a partir do ovo.
> É claro que eu poderia fazer uma busca em todas as incubadoras, 
mas isso
> provocaria uma carga maior no sistema.
>  E outra duvida que surgiu foi em relacao a dupla navegabilidade 
em relacoes
> 1 para 1. Existe algum jeito?
> Pois nesse caso, nao seria uma lista generica, e sim um objeto de 
um tipo
> especifico, o que causaria com certeza uma referencia circular.
>  No caso, nesse mesmo programa, por exemplo, eu tenho o avestruz e 
o ovo de
> origem do mesmo. Seria muito util eu poder saber de que ovo um 
animal veio e
> vice-versa.
>  Type
> TAnimal = Class(TObject)
> Private
>  FOvoOrigem : TOvo;
> ...
> 
> Type
> TOvo = Class(Object)
> Private
> FAnimal : TAnimal;
> ...
> 
> Queria tbm agradecer a tua ajuda. Sei que sou meio chato as vezes, 
mas estou
> apenas tentando solucionar as minhas duvidas.
>   Sds.
>  Francisco
>  On 11/18/05, Romario (Listas) <[EMAIL PROTECTED]> wrote:
> >
> > Francisco,
> >
> > Pelo que estou entendendo, você não precisará fazer um typecast 
do
> > objeto. Só precisará recuperá-lo na lista, como informei 
anteriormente.
> >
> > Ex.: Endereco := Pessoa.lstEnderecos.Items[i];
> >
> > O typecast seria : Endereco := TEndereco
(Pessoa.lstEnderecos.Items[i]);
> >
> > Obs.: Não tenho como testar aqui, mas acredito que não seja 
necessário.
> >
> > Quanto ao erro, acho que é impossível de acontecer porque a 
lista é
> > criada, populada por um único tipo de objeto e destruída após a
> > utilização. Não vejo porque você adicionaria tipos diferentes de 
objetos
> > na lista.
> >
> > Ainda não entendi porque você faz tanta questão que a 
navegabilidade
> > esteja nos dois sentidos. Para que um Endereco ia querer saber a 
quem
> > ele pertence?
> >
> > Sds,
> >
> > Romario
> >
> >
> >
> >
> > Francisco Trindade escreveu:
> > > rs... agora estamos nos entendendo..
> > > tudo bem, entao na criacao do objeto pessoa (ou em outro 
momento, se fo
> > > utilizado um *lazy loading*), a funcao sobre a qual estavamos 
discutindo
> > > busca os enderecos da pessoa e povoa a lista, que esta no 
objeto Pessoa.
> > > rs...entao acho q estavamos falando a mesma coisa, apenas nao 
nos
> > > entendendo direito.
> > > Tudo bem, agora que concordamos nesse ponto, posso voltar a 
minha duvida
> > > original (espero que possamos concordar nisso tbm!)
> > > O objeto pessoa teria uma lista, dessa forma:
> > > Type
> > > TPessoa = Class(TObject)
> > > Private
> > > FCodigo : Integer;
> > > FNome : String;
> > > LstEndereco : TList;
> > > Protected
> > > ...
> > > Public
> > > Constructor Create;
> > > Property Codigo : Integer Read FCodigo;
> > > Property Nome : String Read FNome Write FNome;
> > > *Property Enderecos : TList Read LstEndereco Write LstEndereco;
> > >
> > > * *Function ListaPessoas: TList; Virtual; Abstract;*
> > > End;
> > > O problema que eu vejo nisso é que ListaPessoas é uma TList, 
ou seja,
> > uma
> > > lista genérica.
> > > Quando eu acessar Pessos.Enderecos, teria que fazer um 
typecast dos
> > objetos
> > > que estao nela, para obter o objeto do tipo Endereco.
> > > E fazendo esse typecast, corro o risco de criar erros no 
sistema, já que
> > > pode ser que em algum momento, por um engano, eu poderia 
colocar uma
> > classe
> > > de outro tipo na lista de enderecos, e o compilador nao 
acusaria nada.
> > > O que poderia ser feito é uma lista especializada, que 
descenda de
> > TList, e
> > > trabalhe apenas com objetos do tipo Endereco.
> > > Mas dai, nesse caso, eu nao poderia, na classe endereco, ter 
uma
> > referencia
> > > para a pessoa a qual pertence o endereco, na forma:
> > >
> > > Type
> > > TEndereco = Class(TObject)
> > > Private
> > > *FPessoa : TPessoa;*
> > > Protected
> > > pq dai aconteceria uma referencia circular, entre TPessoa e 
TEndereco.
> > > Imagino que tu uses a TList generica, conforme o teu exemplo. 
Mas tu nao
> > > acha que isso pode acarretar em erros no codigo?
> > > Sds.
> > > Francisco
> > >
> > > On 11/17/05, Romario (Listas) <[EMAIL PROTECTED]> wrote:
> > >
> > >>A classe endereço *NÃO* tem uma lista de todos os endereços 
existentes,
> > >>ela tem um método que recebe um objeto Pessoa ou apenas o 
código dessa
> > >>pessoa e efetua uma busca no banco para trazer o(s) endereço
(s) que
> > >>estiver(em) relacionado(s) à essa pessoa.
> > >>
> > >>Quem tem uma lista (apenas uma lista) com um ou vários objetos 
Endereco
> > >>é o objeto Pessoa. Ele solicitou à classe Endereco que fosse 
ao banco de
> > >>dados e trouxesse todos os endereços que estivessem 
relacionados com
> > >>ela. A classe Endereco por sua vez, faz a solicitação à camada 
de
> > >>persistência que busca os dados, lê cada um dos registros 
recuperados,
> > >>cria um objeto para cada endereço encontrado e popula a lista.
> > >>
> > >>Nenhum objeto deve ter acesso aos dados de outro objeto que 
não seja por
> > >>solicitação direta. A exceção só existe para atributos 
públicos. Ou
> > >>seja, se você precisa saber o endereço da Pessoa, pergunte à 
ela que ela
> > >>pergunta ao Endereco e ele repassa a informação.
> > >>
> > >>Ex.:
> > >>
> > >>{Isso será feito no Formulário (Depois de populado o objeto)}
> > >>
> > >>Endereco := Pessoa.lstEnderecos.Items[i];
> > >>
> > >>edtLogradouro.Text := Endereco.Logradouro;
> > >>edtNumero.Text := Endereco.Numero;
> > >>edtComplemento.Text := Endereco.Complemento;
> > >>edtBairro.Text := Endereco.Bairro;
> > >>...
> > >>
> > >>Fiquei na dúvida do "... seu eu conhecer..." e vou deduzir o 
que seja
> > >>para tentar explicar.
> > >>
> > >>Para saber o endereço da Pessoa você terá *OBRIGATORIAMENTE* 
que
> > >>conhecê-la. Qual a finalidade de se ter um endereço cadastrado 
sem poder
> > >>ter uma Pessoa associada à ele? Não existe, não é???
> > >>
> > >>Nesse caso, quem fará uso do "Class Function ListaEnderecos
(oPessoa:
> > >>TPessoa): TList;" é o objeto Pessoa quando for criado e 
populado.
> > >>
> > >>Me fiz entender dessa vez?
> > >>
> > >>Caramba!!! Onde estão os autores de livros, mestrandos, 
doutorandos e
> > >>experts em orientação a objetos que não opinam nessa thread? :-
D
> > >>
> > >>Sds,
> > >>
> > >>Romario
> >
> >
> >
> >
> >
> > _______________________________________________________
> > Yahoo! Acesso Grátis: Internet rápida e grátis.
> > Instale o discador agora!
> > http://br.acesso.yahoo.com/
> >
> >
> >
> > --
> > <<<<< FAVOR REMOVER ESTA PARTE AO RESPONDER ESTA MENSAGEM >>>>>
> >
> >
> >
> >
> >
> >   *Yahoo! Grupos, um serviço oferecido por:*   PUBLICIDADE
> >
> > 
<http://br.rd.yahoo.com/SIG=12fb7jkjo/M=380335.7481167.8369105.236989
3/D=brclubs/S=2137111264:HM/Y=BR/EXP=1132345048/A=3126093/R=2/id=nosc
ript/SIG=12c39trgo/*http://ad.br.doubleclick.net/clk;22846485;1212006
6;a?http://www.hoteis.com>
> > ------------------------------
> > *Links do Yahoo! Grupos*
> >
> >    - Para visitar o site do seu grupo na web, acesse:
> >    http://br.groups.yahoo.com/group/delphi-br/
> >    - Para sair deste grupo, envie um e-mail para:
> >    [EMAIL PROTECTED]<delphi-br-
[EMAIL PROTECTED]>
> >    - O uso que você faz do Yahoo! Grupos está sujeito aos Termos 
do
> >    Serviço do Yahoo! <http://br.yahoo.com/info/utos.html>.
> >
> >
> 
> 
> --
> --
> Francisco Trindade
> 
> 
> [As partes desta mensagem que não continham texto foram removidas]




-- 
<<<<< FAVOR REMOVER ESTA PARTE AO RESPONDER ESTA MENSAGEM >>>>>

<*> Para ver as mensagens antigas, acesse:
    http://br.groups.yahoo.com/group/delphi-br/messages

<*> Para falar com o moderador, envie um e-mail para:
    [EMAIL PROTECTED]
 
Links do Yahoo! Grupos

<*> Para visitar o site do seu grupo na web, acesse:
    http://br.groups.yahoo.com/group/delphi-br/

<*> Para sair deste grupo, envie um e-mail para:
    [EMAIL PROTECTED]

<*> O uso que você faz do Yahoo! Grupos está sujeito aos:
    http://br.yahoo.com/info/utos.html

 


Responder a