outra dúvida de poo
considerem as classes:
e a descendente:
Vamos supor que eu instancie um objeto fcachorro da classe tcachorro:
agora vamos acessar esse cachorro como sendo um TpitBull, fazendo typecast.
se eu fizer
dá erro de invalid typecast, mas se eu fizer :
desse jeito funciona normalmente.
qual a diferença de se usar Tipo(variavel) e (Variavel as tipo)?
type TCachorro = class(tobject) private Flatido: string; function getLatido: string; procedure SetLatido(const Value: string); protected Mordida: string; public property Latido: string read getLatido write SetLatido; end;
e a descendente:
type TPitBull = class(Tcachorro);
Vamos supor que eu instancie um objeto fcachorro da classe tcachorro:
fcachorro := tcachorro.create;
agora vamos acessar esse cachorro como sendo um TpitBull, fazendo typecast.
se eu fizer
(fcachorro as tpitbull).propriedade
dá erro de invalid typecast, mas se eu fizer :
tpitbull(fcachorro).propriedade;
desse jeito funciona normalmente.
qual a diferença de se usar Tipo(variavel) e (Variavel as tipo)?
Vitor Rubio
Curtidas 0
Respostas
Massuda
03/02/2006
A diferença é que usando o [b:aedda8f670]as[/b:aedda8f670], o compilador gera código adicional que verifica se é possível fazer de modo seguro o typecast de uma classe para a outra (gera exceção se não for seguro) enquanto da segunda forma o compilador acredita que você sabe o que está fazendo.
O que é typecast seguro? Vamos supor que......nesse caso não é seguro fazer o typecast de TCachorro para TPitbull pois TPitbull possui membros/métodos que não existem em TCachorro. O [b:aedda8f670]as[/b:aedda8f670] deve gerar uma exceção; dependendo de diversos fatores, pode ser que você consiga usar o () e forçar o typecast, mas aí estará funcionando por uma feliz coincidência de fatores.
Por outro lado, como TPitbull é derivado de TCachorro, o typecast de TPitbull para TCachorro é seguro pois a classe TPitbull herdou as características de TCachorro; nesse caso o [b:aedda8f670]as[/b:aedda8f670] deve funcionar sem problemas.
O que é typecast seguro? Vamos supor que...
type TPitBull = class(Tcachorro) public Manso: Boolean; end;
Por outro lado, como TPitbull é derivado de TCachorro, o typecast de TPitbull para TCachorro é seguro pois a classe TPitbull herdou as características de TCachorro; nesse caso o [b:aedda8f670]as[/b:aedda8f670] deve funcionar sem problemas.
GOSTEI 0
Vitor Rubio
03/02/2006
Valew! Isso explica muita coisa que eu ignorei durante muito tempo....
GOSTEI 0
Michael
03/02/2006
Typecasts via [b:3b19a781bf]Tipo(Expressão)[/b:3b19a781bf] só devem ser usados para variáveis e valores.
Como um objeto é referenciado através de uma variável, essa forma de typecast tbm funciona, mas como o [b:3b19a781bf]Massuda [/b:3b19a781bf]disse, vc tem que saber o que está fazendo.
Para fazer casts de classes e interfaces, use sempre que possível o operador [b:3b19a781bf]as[/b:3b19a781bf], pelas razões que o colega já explicou.
A segunda maneira utilizada no seu exemplo - [b:3b19a781bf]TPitBull(FCachorro)[/b:3b19a781bf] - deveria gerar uma violação de acesso, pois - novamente o [b:3b19a781bf]Massuda [/b:3b19a781bf]observou bem - as propriedades de [b:3b19a781bf]TPitBull [/b:3b19a781bf]não existem em [b:3b19a781bf]TCachorro[/b:3b19a781bf].
Se rodou sem erros, foi mesmo muita coincidência...
[]´s
var I: Integer; C: Char; begin I := Integer(´A´); // typecast de valor C := Char(I); // typecast de variável end;
Como um objeto é referenciado através de uma variável, essa forma de typecast tbm funciona, mas como o [b:3b19a781bf]Massuda [/b:3b19a781bf]disse, vc tem que saber o que está fazendo.
Para fazer casts de classes e interfaces, use sempre que possível o operador [b:3b19a781bf]as[/b:3b19a781bf], pelas razões que o colega já explicou.
A segunda maneira utilizada no seu exemplo - [b:3b19a781bf]TPitBull(FCachorro)[/b:3b19a781bf] - deveria gerar uma violação de acesso, pois - novamente o [b:3b19a781bf]Massuda [/b:3b19a781bf]observou bem - as propriedades de [b:3b19a781bf]TPitBull [/b:3b19a781bf]não existem em [b:3b19a781bf]TCachorro[/b:3b19a781bf].
Se rodou sem erros, foi mesmo muita coincidência...
[]´s
GOSTEI 0
Vitor Rubio
03/02/2006
não foi coincidencia, na verdade, quem colocou o campo público Manso: boolean foi o Massuda, aí desse jeito não funcionaria.
no meu caso funcionou porque eu declarei assim:
TPitBull = class(Tcachorro);
ou seja, a classe descendente não tinha nada de diferente, só o nome. Se eu tivesse colocado novos métodos e propriedades aí sim ia dar erro...
no meu caso funcionou porque eu declarei assim:
TPitBull = class(Tcachorro);
ou seja, a classe descendente não tinha nada de diferente, só o nome. Se eu tivesse colocado novos métodos e propriedades aí sim ia dar erro...
GOSTEI 0
Dopi
03/02/2006
Uma maneira de evitar exceções é fazer um teste usando o [b:3db8978d39]IS[/b:3db8978d39]
dessa maneira vc poderia declarar uma váriavel do tipo Tcachorro e instanciar qq descendente de Tchachorro nela (como por exemplo TPitBull)... Quando vc quiser acessar uma propriedade especifica de uma classe filha (que não existe na classe pai)... vc usa o teste com IS para verificar se o Objeto instanciado é realmente daquele tipo... se o for, vc usa o TypeCast para acessar as propriedades publicas exclusivas da classe filha.[/code]
if fcachorro is tpitbull then tpitbull(fcachorro).manso := true
dessa maneira vc poderia declarar uma váriavel do tipo Tcachorro e instanciar qq descendente de Tchachorro nela (como por exemplo TPitBull)... Quando vc quiser acessar uma propriedade especifica de uma classe filha (que não existe na classe pai)... vc usa o teste com IS para verificar se o Objeto instanciado é realmente daquele tipo... se o for, vc usa o TypeCast para acessar as propriedades publicas exclusivas da classe filha.[/code]
GOSTEI 0