Newsgroup: it.comp.lang.delphi
Titolo: OOP ed ereditarietà - dubbio!

ciao a tutti,
ho letto su Mastering in Delphi 5 Capitolo 2 il Paragrafo "Late Binding e 
polimorfismo", in questo paragrafo c'è un esempio di ereditarietà con uso 
di metodi virtuali.
L'esempio dichiara una classe base TAnimal e una classe derivata TDog, 
adesso in entrambe è stato dichiarato un metodo Voice, che mostra una 
stringa col verso dell'animale, dove in TAnimal è dichiarato :
procedure Voice; Virtual
mentre in TDog è dichiarato :
procedure Voice; Override;
Adesso nel paragrafo è stato descritto anche il vantaggio di questa 
tecnica, cioè che in fase di esecuzione Delphi riesce a capire quale 
metodo chiamare in base al tipo di oggetto a cui la variabile fa 
riferimento, bene! in effetti se dichiaro due variabili una di tipo 
TAnimal e una di tipo TDog e chiamo per ognuna il metodo Voice viene 
chiamato il rispettivo metodo mostrando il verso dell'animale definito 
nel costruttore della classe.
Un po più avanti nel paragrafo c'è scritto che tutto questo avviene solo 
perchè il metodo viene chiamato Virtual! ma se dalle definizioni tolgo le 
parole Virtual e Override funziona cmq la chiamata al metodo!!!! 
Ora con questo non volgio dire che Marco Cantu ha sbagliato! voglio 
chiedere a voi...Non ho capito niente?
Diego
--- posted by geoForum on 
http://www.delphiedintorni.it


[cuttone]
Non ho letto il libro di cantù e quindi non posso parlare dell'esempio
specifico.
Guarda se questo codice per caso ti chiarisce le idee.
TAnimale = class
  public
    procedure Verso; virtual; abstract;
    procedure FaiFareIlVerso;
  end;
  TCane = class(TAnimale)
  public
    procedure Verso; override;
  end;
  TGatto = class(TAnimale)
  public
    procedure Verso; override;
  end;
implementation
procedure TAnimale.FaiFareIlVerso;
begin
  Verso;
end;
procedure TCane.Verso;
begin
  MessageDlg('BAU!', mtInformation, [mbOk], 0);
end;
procedure TGatto.Verso;
begin
  MessageDlg('MIAO!', mtInformation, [mbOk], 0);
end;
procedure TForm1.CaneButtonClick(Sender: TObject);
begin
  with TCane.Create do
  begin
    FaiFareIlVerso;
    Free;
  end;
end;
procedure TForm1.GattoButtonClick(Sender: TObject);
begin
  with TGatto.Create do
  begin
    FaiFareIlVerso;
    Free;
  end;
end;
Come vedi la Procedura FaiFareIlVerso chiama una procedura virtuale.
In fase di compilazione NON sa quale verso deve fare.
Prova a togliere l'abstact e fare unaa procedura Verso generica e poi
togli pure virtual e override, vedrai che succede ;-)
Ciao.
-- 
Ore 18.30: premo invio.

Non esiste solo quello che accade a runtime.
Hai x caso notato se il buon delphi ti segnala dei warning quando
compili?
Nel caso, spero tu non faccia parte di quel partito trasversale di
sviluppatori che se ne fottono dei warning restituiti dai
compilatori... ;-P
AS

 compilatori... ;-P
Ho programmato su macchine UNIX in linguaggio ANSI C compilando i 
sorgenti con un Makefile, mi è capitato molte volte di trovarmi di fronte 
a dei Warning che poi si sono rivelati cause di "core dump" e l'utility 
GDB non ti aiuta sempre come dovrebbe!!!


 togli pure virtual e override, vedrai che succede ;-)
Ho fatto le prove che mi hai descritto, nel primo caso togliendo abstract 
ho dovuto creare un metodo generico di Verso e togliendo virtual e 
override il metodo FaiFareIlVerso chiamava sempre il metodo Verso della 
classe base.
Nel caso che avevo letto io chiamavo direttamente il metodo virtuale, ma 
facendo cosě č come se chiamassi la ridefinizione del metodo base come se 
fossero metodi statici vero?


 sbagliato! voglio chiedere a voi...Non ho capito niente?
Oltre all'ottimo esempio di Massimo devi sempre tener
presentel'importanza della variabile d'istanza. Nella tua form dichiara
una variabile d'istanza di tipo TAnimale e poi nei relativi OnClick
esegui il codice seguente:
procedure TForm1.CaneClick(Sender: TObject);
begin
  fAnimale := TCane.Create;
  fAnimale.FaiFareIlVerso;
  fAnimale.Free;
end;
procedure TForm1.GattoClick(Sender: TObject);
begin
  fAnimale := TGatto.Create;
  fAnimale.FaiFareIlVerso;
  fAnimale.Free;
end;
Questo ti puň aiutare a capire il problema che hai avuto, ovvero la
dichiarazione della variabile č di importanza fondamentale. E' un caso
di Template Method pattern e la VCL ne č ricca. Tieni presente,
tuttavia, che dichiarando la variabile d'istanza come di tipo TAnimale
non potrai vedere i metodi aggiunti nelle classi che ereditano da essa
a meno di non effettuare dei casting.
-- 
guastatore
ICLDweb: 
http://www2.samatel.com/icld/

 ereditano da essa a meno di non effettuare dei casting.
Allora in questo caso preferisco utilizzare una variabile che punti 
direttamente al suo tipo per poter accedere ai suoi metodi, questo perchč 
effettuare molte operazioni con RTTI, ho letto, che ha un impatto 
negativo sulle prestazioni ( naturalmente qui si parla di grosse 
gerarchie!!!! ) quindi sarebbe meglio dare piů importanza al polimorfismo.
sempre IMHO!!! ;p


 polimorfismo.
Dipende da ciò che devi realizzare. Ereditarietà e polimorfismo sono
aspetti strettamente legati.


Diego
spero di essermi spiegato.
	Ciao
	MassimoB
 
---------------------------------
http://www.massimobeschi.it/
---------------------------------
Se tu pagare come dici tu ...
Io lavorare come dico io ...
Se tu pagare come dico io ...
Io lavorare come dici tu ...
---------------------------------

 spero di essermi spiegato.
Sei stato molto chiaro, quello che hai scritto fa parte delle cose che 
avevo letto ma leggerle nel modo come lo hai spiegato tu mi ha fatto bene 
anche se con la OOP devo fare ancora molta strada.
grazie.
