Array
(
)

override overload virtual ... Duvidas

Marco Salles
   - 27 mar 2006

na secção interface de um form escrevi a titulo de experiencia as seguintes classes

#Código

type
TAnimal =class
private
function Voice:String;Virtual;
end;

#Código
type
TDog =Class(TAnimal)
private
function voice:String;Overload;
function Voice(indice:integer):String;Overload;
end;

#Código
type
TCat=Class(TAnimal)
function voice:String;Override;
end;


e na parte implementation:

#Código
{ TAnimal }

function TAnimal.Voice: String;
begin
result:=´Sou um Animal´;
end;

#Código
{ TDog }

function TDog.voice: String;
begin
result:=´Sou um cachorro´;
end;

function TDog.voice(indice: integer): String;
begin
case indice of
0:result:=´Sou um cachorro manso´;
1:result:=´Sou um cachorro bravo´;
end;
end;

#Código
{ TCat }

function TCat.voice: String;
begin
result:=´Sou um gato´;
end;


declarei ainda uma variavel MyAnimal , logo abaixo da secçao implementation

#Código
implementation

{$R *.dfm}

var
MyAnimal:TAnimal;


Nesse formulario tenho cinco botoes cujo os nomes são bem sujestivos :

#Código
procedure TForm1.CriarAnimalClick(Sender: TObject);
begin
MyAnimal:=TAnimal.Create;
end;


#Código
procedure TForm1.CriarCachorroClick(Sender: TObject);
begin
MyAnimal:=TDog.Create;
end;


#Código
procedure TForm1.CriarGatoClick(Sender: TObject);
begin
MyAnimal:=TCat.Create;
end;


//Chama o metodo
#Código
procedure TForm1.metodoVoiceCachorroClick(Sender: TObject);
begin
showmessage(Tdog(MyAnimal).voice);
MyAnimal.Free;
end;


/chama o método
#Código
procedure TForm1.MetodoVoiceCatClick(Sender: TObject);
begin
showmessage(Tcat(MyAnimal).voice);
MyAnimal.Free;
end;



Ate ai tudo bem ...
Executar o MetodoVoiceCatClick sem ter instanciado o Objeto..Isto é , sem ter ´criado´ o MyAnimal :arrow:

Obtenho um ERRO... De Acesso ... Como deveria

a dúvida é... Ao executar evento Onclick do botão metodoVoiceCachorroClick eu não obtenho nenhum ERRO ???? parece que esse métodos ja estão alocados na memoria do computador ????
eu não precisei instanciar a variavel MyaNIMAL para executar esse métodos da Calsse TDOG ???

porque dois pesos e duas medidas ???

Obrigado...


Ipc$
   - 27 mar 2006

Ao que parece, o Delphi criou uma class function de voice.


Massuda
   - 27 mar 2006


Citação:
=´Marco Salles´]eu não precisei instanciar a variavel MyaNIMAL para executar esse métodos da Calsse TDOG ??? Tenho a impressão que, dependendo da ordem de execução, seu programa pode dar erro tanto em metodoVoiceCachorroClick como em MetodoVoiceCatClick.

Alguns erros que podem ocorrer...[list:c79190befb][*:c79190befb]Executar MetodoVoiceXxxClick sem ter chamado CriarXxxClick deve dar um AV[*:c79190befb]Executar MetodoVoiceXxxClick duas vezes seguidas pode dar um AV[*:c79190befb]Executar CriarXxxClick seguindas vezes pode deixar memória sem liberar[/list:u:c79190befb]

Com relação à classe TDog, nela você redeclarou o método Voice de modo que esse método não é mais virtual (faltou um override). Como esse método não é mais virtual, ele passa a ser um endereço fixo na tabela de métodos da classe, de modo que, na minha opinião (não testei) você não depende de ter um objeto para acessar a classe.


Marco Salles
   - 27 mar 2006


Citação:
Ao que parece, o Delphi criou uma class function de voice.


Quem criou tudo foi eu..


Citação:
Com relação à classe TDog, nela você redeclarou o método Voice de modo que esse método não é mais virtual (faltou um override).


Fiz isto propositalmente....


Citação:
Como esse método não é mais virtual, ele passa a ser um endereço fixo na tabela de métodos da classe,

é o que tudo indica , mas é estranho, porque supondo que a classe tenha outros métodos virtuais ou overrides , teremos nesta classe , algumas definiçoes fixas e outra que serão criadas quando o objeto for instanciado ???


Citação:
de modo que, na minha opinião (não testei) você não depende de ter um objeto para acessar a classe.


Eu testei e é sobre isto que levanto esta dúvida

Sera , <tb não testei> que se tiver pelo menos um método Virtual(Ou Override) nesta Classe(TDog) seje suficiente para que todos os outros métodos , não sejam mais carregados na memória (com endereço fixo)
?????????


Massuda
   - 27 mar 2006


Citação:
...porque supondo que a classe tenha outros métodos virtuais ou overrides , teremos nesta classe , algumas definiçoes fixas e outra que serão criadas quando o objeto for instanciado ?
Sim. Métodos virtuais só podem ter seu endereço determinado em tempo de execução. Sem isso, não teria como polimorfismo funcionar.


Citação:
...se tiver pelo menos um método Virtual(Ou Override) nesta Classe(TDog) seje suficiente para que todos os outros métodos , não sejam mais carregados na memória (com endereço fixo)?
Todos os métodos estão na memória e tem endereço fixo. O que acontece é que cada objeto tem uma tabela que diz qual método dinâmico/virtual deve ser usado; para os métodos estáticos (sejam eles da classe ou do objeto) essa tabela não é necessária. No seu caso, como você fez Voice ser um método estático não está sendo necessário usar a tabela de métodos virtuais não precisa ser consultada.

Agora, Delphi tem alguns furos na implementação de POO... um deles é esse que seu código está demonstrando, ou seja, acessar um método estático através de um objeto nil. Outras linguagens não permitem isso e conceitualmente esse é o comportamento correto.


Ipc$
   - 27 mar 2006

Neste caso, me parece que quando se faz:#Código

function Voice: String;
é o mesmo que:#Código
class function Voice: String;