Newsgroup: it.comp.lang.delphi
Titolo: OOP: posso fare una cosa del genere?

Ho delle classi abbastanza diverse ma per alcune di esse mi serve
implementare le stesse proprietà, con lo stesso comportamento. E' possibile
creare una classe 'comune' che contiene queste proprietà per poi
'aggiungerle' alle classi in cui mi servono?
Non massacratemi se ho scritto una boiata ;-)
-- 
Lis
ICQ@Home #7317603sette     ICQ@Work #16285702tre
Mercatino: 
http://lis77.bravepages.com
 (aggiornato *con foto*: 16/06/03)

 Non massacratemi se ho scritto una boiata ;-)
Se ho ben capito e se ricordo bene gli studi di qualche anno fa... dovresti
usare l'ereditarietà, in pratica ti crei una classe con tutti i metodi che
ti servono e la lasci li dov'è, quando crei le altre classi che devono avere
quelle cose in comune erediti le proprietà della prima classe e aggiungi
quelle che vuoi...
ad esempio quando il "widzard" crea una nuova form leggi questo riguardo la
sua classe:
type
  TForm1 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;
questo  TForm1 = class(TForm) indica che TForm1 erediterà tutte le proprietà
di TForm, in più potrai aggiungere tutto quello che vuoi sotto:
   private
    { Private declarations }
  public
    { Public declarations }
Spero di essere stato chiaro abbastnza :)


Open Delphi Manual (
http://groups.yahoo.com/group/delphi_open_manual/
)

 quelle che vuoi...
sì, le classi sono già strutturate in una gerarchia e il problema è appunto
questo ;-)


 Ho già pronto il macete...preparati che sto arrivando... ;-)
Non si scrive machete? :-pp


 per poi 'aggiungerle' alle classi in cui mi servono?
Per non sapere ne' leggere ne' scrivere, e per non aver capito la
domanda, direi che piu' che una classe vuoi che la tua gerarchia abbia
in comune una interfaccia. L'unico _problema_ e' che una interfaccia non
puo' avere proprieta' ma metodi.
Alternativamente, se credi opportuno e _ci sta_, puoi fare delle
proprieta' _comuni_ una classe a parte, da includere nelle classi
"abbastanza diverse" per composizione.
Saluti
Paolo Arosio

 Non si scrive machete? :-pp
Sì, mi sono sbagliato, ma tagliava lo stesso... ;-)
Buon lavoro!


'aggiungerle' alle classi in cui mi servono?
E` esattamente lo scopo della OOP.

 Paolo Arosio
Andrea

 E` esattamente lo scopo della OOP.
Come non detto...ho visto nell'help che le interfacce in pratica contengono
solo le dichiarazioni, mentre io cercavo di "portare" anche
l'implementazione comune alle classi che mi interessano


 "abbastanza diverse" per composizione.
Cosa intendi per in includere una classe in un altra?


puoi avere sono i campi, ma le proprietą( se hanno dei metodi Set/Get  ) si.
Paolo si riferiva, evidentemente, a ciņ che si intende per "proprietą"
in OOP, non nel gergo di Delphi, e cioč i *campi* di una classe.
E` il motivo per cui, nelle interfacce, le gli specificatori read e
write delle proprietą DEVONO essere metodi.

l'implementazione comune alle classi che mi interessano
Scusa, ma lo scopo della costruzioni di una gerarchia di classi è
proprio quello di consentire di avere un comportamento di base,
ereditabile ed estendibile dalle classi figlie.  Detto in questi
termini, secondo me quello che tu vuoi fare si può fare.  Non so,
però, nello specifico, che cosa vuoi fare esattamente.

 ) si.
Giusto. Le ho addirittura usate in quel paio di unit che avevo scritto
per usare EOS alla fine dell'anno scorso.
/ della serie, quando non sei sicuro di quel che scrivi, controlla
Saluti
Paolo Arosio

 Cosa intendi per in includere una classe in un altra?
Vedi la property Font per TControl e discendenti. Ovviamente, sarebbe
bene che la classe contenuta fosse indipendente dalla classe esterna che
la contiene.
Saluti
Paolo Arosio

 l'implementazione comune alle classi che mi interessano
Una domandina...
Ma queste classi derivano tutte da TObject?

bugger wrote:

Ovviamente intendevo "DIRETTAMENTE" da TObject.
O da qualsiasi altra classe base comune?

 (ora sto facendo così)
Per me il problema reale è saper cosa intendi fare in un secondo tempo con
il tuo progetto.
Hai intenzione di svilupparlo ulteriormente allora ti conviene definire una
gerarchia in cui le varie classi si differenzino tra loro in modo chiaro.
Se la riusabilità del codice non è alta allora puoi fare ciò che hai detto
in precedenza ossia assegnare l'impementazione diversa a seconda della
classe in questione e mantenere il nome della proprietà lo stesso in tutte
quelle che ti servono.
Ciao
--------------------------------
Inviato via 
http://usenet.libero.it

 (ora sto facendo così)
Vedo alcune soluzioni possibili:
(a) Inserisci il codice in FsItem. Se vuoi, puoi proteggerlo (protected) 
e renderlo pubblico (public) solo nelle classi derivate.
(b) Inserisici il codice nelle tre classi, se necessario puoi usare 
un'interfaccia per usare quel codice in modo uniforme anche se non è 
definito in una classe padre comune.
(b1) Se non vuoi riscrivere il codice a mano, puoi usare il 
preprocessore del Delphi per includere un file esterno nelle tre classi.
-- 
Roberto Lupi

 (b) Inserisici il codice nelle tre classi, 
Alla fine ho fatto cosě, ho ripetuto un pň di codice ma č abbastanza chiaro


 gerarchia in cui le varie classi si differenzino tra loro in modo chiaro.
Siccome è in previsione di usare questa struttura anche in altri progetti
alla fine ho deciso di creare 2 classi di raggruppamento TFsCustomFile e
TFsCustomFolder (derivate da TFsItem) da cui derivo i singoli casi
particolari.


 O da qualsiasi altra classe base comune?
Guarda la risposta a Marco Breveglieri, solo TFsItem deriva da TObject,
tutte le altre sono strutturate in una sorta di gerarchia


 però, nello specifico, che cosa vuoi fare esattamente.
Ti faccio un esempio pratico:
nella proprietà Name di TFsFile e TFsFolder devo valorizzare il nome dos
(8.3) e il nome lungo, mentre nella classe TFsFolderArchive e TFsFileArchive
devo valorizzare solo il nome lungo. Quindi le 2 classi sono in parte simili
perchè entrambe rappresentano file o directory, ma un una coppia la
proprietà Name si "sdoppia", nell'altra no.


proprietà Name si "sdoppia", nell'altra no.
Non so in che relazione siano TFsFolderArchive e TFsFileArchive con le
altre due classi, nè che cosa siano destinate a contenere.

 altre due classi, nè che cosa siano destinate a contenere.
                  FsItem
                 /       \
     FsCustomFile         FsCustomFolder
    /     |                 /      \
FsFile    |         FsFolder        FsFolderArchive
        FsFileArchive                       \
                                             FsArchive
FolderArchive e FileArchive rappresentano dei file e cartelle (quindi con
dimensione, attributi, data, ecc che prendono ta CustomFile e CustomFolder)
e altre proprietà aggiuntive (per esempio, un commento).
Quindi FsFile e FsFileArchive sono 'sorelle', così come lo sono FsFolder e
FsFolderArchive. In questa struttura io dovrei aggiungere la "doppia"
proprietà Name alle classi FsFile, FsFolder e FsArchive


proprietà Name alle classi FsFile, FsFolder e FsArchive
Probabilmente non ho ben capito lo schema, ma cosa ti vieta di
aggiungere la proprietà ShortName e la proprietà LongName solo nelle
classi interessate ?

 classi interessate ?
Già, lo schema non è proprio immediato da capire...
comunque le proprietà le ho aggiunte alle 3 classi, ma siccome si tratta di
codice identico stavo semplicemente chiedendo se era possibile, in qualche
modo, scriverlo solo una volta e poi 'farlo usare' alle mie 3 classi, più
che altro per una questione stilistica che per pura necessità.
Infine, non utilizzo le proprietà con nome diverso perchè così nel programma
che le utilizza, richiamando la semplice proprietà Name ho il nome del
file/cartella nel formato selezionato (tramite una proprietà di classe)
senza dover fare ogni volta delle distinzioni tra Name (per le classi che
non hanno long e short name), LongName e ShortName


non hanno long e short name), LongName e ShortName
Io ho fatto, su due piedi, qualcosa del genere, vedi se ti va bene:
type
  TNamedClass = class
  protected
    function GetName: String; virtual; abstract;
    procedure SetName(AName: String); virtual; abstract;
  public
    constructor Create(AName: String); virtual; abstract;
    property Name: String read GetName write SetName;
  end;
  TShortNamedClass = class(TNamedClass)
  private
    FShortName: String;
  protected
    function GetName: String; override;
    procedure SetName(AName: String); override;
  public
    constructor Create(AName: String); override;
  end;
  constructor TShortNamedClass.Create;
  begin
    FShortName := AName;
  end;
  function TShortNamedClass.GetName;
  begin
    Result := FShortName;
  end;
  procedure TShortNamedClass.SetName;
  begin
    FShortName := AName;
  end;
type
  TLongNamedClass = class(TNamedClass)
  private
    FLongName: String;
  protected
    function GetName: String; override;
    procedure SetName(AName: String); override;
  public
    constructor Create(AName: String); override;
  end;
  constructor TLongNamedClass.Create;
  begin
    FLongName := AName;
  end;
  function TLongNamedClass.GetName;
  begin
    Result := FLongName;
  end;
  procedure TLongNamedClass.SetName;
  begin
    FLongName := AName;
  end;
  procedure ShowName(NamedObj: TNamedClass);
  begin
    ShowMessage(NamedObj.Name);
  end;
procedure TForm1.Button1Click(Sender: TObject);
var
  snobj: TShortNamedClass;
  lnobj: TLongNamedClass;
begin
  snobj := TShortNamedClass.Create('pippo.txt');
  lnobj := TLongNamedClass.Create('This is a long name.txt');
  try
    ShowName(snobj);
    ShowName(lnobj);
  finally
    if Assigned(snobj) then snobj.Free;
    if Assigned(lnobj) then lnobj.Free;
  end;
end;

 
Vedo se può essermi utile nel mio progetto, grazie 1000 per il tempo
dedicatomi
