Newsgroup: it.comp.lang.delphi
Titolo: [?] Creabilità delle classi: ex programmatori VB, I need your help :)

Mi rivolgo specialmente a voi che provenite dal Visual Basic... 
ricordate le classi VB? Potevano essere private, pubbliche non creabili, 
multiuso, globali multiuso, eccetera. Ebbene: come si fa a rendere 
pubblica non creabile una classe Delphi? ossia, per chi NON proviene dal 
VB, come si fa a fare in modo che una classe possa essere creata solo 
dalla Unit in cui è dichiarata? pur rimanendo visibile dall'esterno? 
dichiarare constructor e destructor come private mi lascia perplessa, ho 
l'impressione che dall'esterno siano ancora visibili i Create e Destroy 
ereditati da TObject...

 dalla Unit in cui è dichiarata? pur rimanendo visibile dall'esterno?
avrei capito se la classe doveva essere visibile solo all'interno dell'unit
che la conteneva, ma a questo punto ti faccio una domanda io.
Che me ne faccio di una classe ( visibile all'esterno della sua unit ) di
cui non è possibile utilizzare il costruttore e quindi la classe intera ?
Ti saluto.....ciao !!
Antonio Tarolla

intera ? 
immaginavo questa risposta... (la risposta breve è: se in VB c'era, 
significa che serviva a qualcosa, no?)
allora, in VB ad esempio c'era un controllo CoolBar, che aveva una 
proprietà enumerabile (apropos, ci sono proprietà enumerabili in Delphi? e 
non parlo delle proprietà con indici...) Bands, di tipo Bands (in Delphi 
sarebbe stata TBands, immagino), con una proprietà predefinita Item che 
restituiva un oggetto di tipo Band (TBand, nella lingua dell'oracolo). 
Allora, che senso avrebbe permettere la creazione di una collezione Bands 
senza un controllo CoolBar? e poi che ci fai con le tue Bands, la birra? 
eppure non si può nascondere completamente la classe Bands (TBands), 
dichiarando ad esempio la proprietà Bands come Object (TObject), perchè a 
design time è un casino, senza il completamento automatico, e in Delphi 
temo che la compatibilità COM non sia forzata come in VB, e quindi le 
chiamate ai membri di una classe non vengono fatte per nome, e quindi giù 
di warning ed errori a compile time. Il costruttore _è_ visibile, ma NON 
dall'esterno: che se ne fa l'esterno? che gliene frega? la classe la deve 
usare solo per tipizzare correttamente le proprietà di un'altra classe

 usare solo per tipizzare correttamente le proprietà di un'altra classe
La cosa + pulita che puoi fare è fare in modo che nel constructor di TBands
(seguendo il tuo esempio) si controlli che abbia come owner un TCoolbar...
if Not( Owner is TCoolbar) then
  raise Exception.Create....
Cmq, sinceramente, a te chetti frega se il costruttore è visibile o no???
sarà il programmatore che eviterà di istanziare qualcosa che non deve
istanziare... va bene mettere dei vincoli di visibilità ma non esageriamo!
Tu lasciagli _tentare_ di creare la classe, se sei in condizioni non ideali
sarà l'oggetto a sollevare un eccezione e "distruggersi"...
Ciao :-)
--
Andrea Magni
E-Mail: 
ama...@interac.it

dichiarare constructor e destructor come private mi lascia perplessa, 
Dichiarare constructor e destructor come private e' semanticamente
errato, perche' i costruttori e i distruttori devono essere usati
PROPRIO dal pubblico di quella classe.
Sei sicuro che non ti serva una classe che implementi il pattern
singleton ? cioe' che sia istanziabile una sola volta ?
In questo modo tutte le altre volte che viene istanziata, restituisce
l'istanza gia' presente, e non permette un'ulteriore creazione.
In C++ si costruisce facilmente, in Delphi non credo si possa (ma non
ho provato).
--
Andrea Laforgia (ICQ 87230455)
http://www.geocities.com/AndreaLaforgia
"ci sono tre tipi di persone nel mondo : quelli che
 sono bravi in matematica e quelli che non lo sono."

 usare solo per tipizzare correttamente le proprietà di un'altra classe
qui non ti ho capito oppure ho perso il filo del discorso. Comunque una
classe Delphi, è un tipo di dato che serve per rappresentare un oggetto.
Per ora ti saluto.....se hai ancora dubbi scrivi ancora.
Ciaoo !!
Antonio Tarolla

usare solo per tipizzare correttamente le proprietà di un'altra classe
Non capisco bene che cosa vuoi fare.
Tutte le classi sono tipi.
Tutte le classi devono poter essere istanziate (a meno che non
contengano metodi virtuali puri).
Non capisco come tu possa definire una proprieta' nella tua classe,
senza poterla costruire !
L'unica cosa che puoi fare e' rendere la classe privata all'unita' di
traduzione e quindi non farla comparire nella sezione di interfaccia
della unit.


 ha scritto nel messaggio
news:Xns9028C699...@127.0.0.1...

L'unico modo che mi viene in mente e' quello di utilizzare le interface
supportate da Delphi, ma non so come funzionino se definite come proprieta'.
Saluti,
Stefano



Forse non ho capito bene, ma mi sembra che il tuo sia il classico
problema delle classi Singleton, ovvero per cui sia possibile creare
una sola istanza, pur essendo la classe pubblica. Anche se non e'
questo il problema, ti possono servire come linea guida per
implementare classi da cui puoi controllare la fase di creazione. Ti
allego l'esempio che puoi trovare in PatternExplorer, un archivio di
pattern disponibile free a
www.geocities.com/yosemite/rapids/4195/delphi.htm
type 
  TProgressor = class (TObject) 
  private 
    FProgress: Integer; 
  protected 
    constructor CreateInstance; 
    class function AccessInstance(Request: Integer): TProgressor; 
    procedure SetProgress(Value: Integer); 
  public 
    constructor Create; 
    destructor Destroy; override; 
    class function Instance: TProgressor; 
    class procedure ReleaseInstance; 
    procedure StartProgress; 
    property Progress: Integer read FProgress write SetProgress; 
  end; 
//Occhio: in questo modo il costruttore diventa inaccessibile!
//Per istanziare la classe si usa Instance, e in questo modo
//il processo diventa controllabile
constructor TProgressor.Create; 
begin 
  inherited Create; 
  raise Exception.CreateFmt('Access class %s through Instance only', 
      [ClassName]); 
end; 
constructor TProgressor.CreateInstance; 
begin 
  inherited Create; 
end; 
destructor TProgressor.Destroy; 
begin 
  if AccessInstance(0) = Self then AccessInstance(2); 
  inherited Destroy; 
end; 
class function TProgressor.AccessInstance(Request: Integer):
TProgressor; 
  const FInstance: TProgressor = nil; 
begin 
  case Request of 
    0 : ; 
    1 : if not Assigned(FInstance) then FInstance := CreateInstance; 
    2 : FInstance := nil; 
  else 
    raise Exception.CreateFmt('Illegal request %d in AccessInstance', 
        [Request]); 
  end; 
  Result := FInstance; 
end; 
class function TProgressor.Instance: TProgressor; 
begin 
  Result := AccessInstance(1); 
end; 
class procedure TProgressor.ReleaseInstance; 
begin 
  AccessInstance(0).Free; 
end; 
procedure TProgressor.SetProgress(Value: Integer); 
begin 
  { Place here the implementation of the progress mechanism ] 
end; 
procedure TProgressor.StartProgress; 
begin 
  { Placehere the implementation of the progress mechanism ] 
end; 
Ciao
--
Piero Bonanno
bop...@libero.it
pie...@tiscalinet.it
bop...@tin.it
bpie...@hotmail.com
______________________________________________
"Madame, lei ha tra le gambe uno strumento
che puo' offrire piacere a migliaia di persone,
e tutto quello che sa fare e' grattarlo"
- Sir Thomas Beechan a una violoncellista

fatte con un certo criterio.
ooooh, sia rigraziato il cielo! ecco quello che cercavo
mille grazie

della unit.
ma poi devo dichiarare tutte le proprietą che fanno riferimento alla classe 
come TObject...

singleton ? cioe' che sia istanziabile una sola volta ?
no, so cosa voglio, e non è questo... questo che dici è grosso modo 
l'equivalente delle classi pubbliche multiuso in Visual Basic, in cui la 
classe fa da vero e proprio server, e ogni volta che viene istanziata 
restituisce l'istanza esistente

costretta VB, io ne so qualcosa  ;-)
ora non esageriamo
di OOP so praticamente tutto, terminologia a parte
diciamo che mi basta trovare un nome per ogni cosa che in VB non si può fare 
:) (ad esempio ho scoperto che "quella cosa là con le funzioni e gli 
operatori" si chiama overloading, che "quella cosa là con le classi" si 
chiama ereditarietà, eccetera)

:)
Be' allora preparati a cercarne molti di termini specie se ti accingi
ad avvicinarti a Delphi (per non parlare di C++).
Un consiglio, mai dire : "di questo argomento so praticamente tutto".
C'e' sempre qualcosa di sconosciuto dietro l'angolo :)
