Autor Beitrag
chubbson
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 32
Erhaltene Danke: 1



BeitragVerfasst: Do 25.06.09 11:57 
Ich hab das gefühl .. ich stell nur noch Basic fragen... Trotzdem finde ich nirgends Antwort darauf.

Es geht darum Ich habe eine grund Klasse TBasic die von TObject ableitet
Diese Besitzt 2 Create Constructoren mit Parameter
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
TBasic = class(TObject)
    private
      constructor Create(); overload//Damit möchte ich default Create für TBasic Objekte verstecken, ist das möglich?
    public
      constructor Create(param1: string); overloadvirtual;                 //EIn Objekct muss mit entweder mit 1 Parameter 
      constructor Create(param1: string; param2: string); overloadvirtual//oder 2 Parameter erzeugt weren
end;



Dann habe ich TAdvance die von TBasic ableitet.. hier ist mehr oder weniger alles Abstract.. sie darf keine eigenen Constructoren haben.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
TAdvance = class( TBasic )
      private
        constructor Create(); //Damit möchte ich default Create für TBasic Objekte verstecken, ist das möglich?
      public
        ;
end;



Dann gibt es noch TExpert die von TAdvance ableitet.. hier sollen die abgeleitete 2 Create Constructoren von TBasic zur verfgung stehen und dann weiter verarbeitet werden mit Inherit.
Aber es darf auch hier kein Default Creat zur verfügung stehen. So das man ein Objekt zwingend mit Parameter erzeugen muss
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
TExpert = class( TAdvance )
      private
        constructor Create(); //Damit möchte ich default Create für TBasic Objekte verstecken, ist das möglich?
        procedure doInitialize();
      public
        constructor Create(param1: string); overloadoverride;                 // Beim Compilieren Motzt er uns sagt "Previous declaration of 'Create' was not marked with the 'overload' directive"
        constructor Create(param1: string; param2: string); overloadoverride// Beim Compilieren Motzt er uns sagt "Previous declaration of 'Create' was not marked with the 'overload' directive"
        //Falls ich auf die override Creates verzichte kannich kompilieren.. jedoch nutzt mir das nich da ch in den creates do initialize aufrufen möchte
end;
....

procedure TExpert.doInitialize;
begin
  //Do Something
end;

constructor TExpert.Create(param1: string);
begin
  inherited;

  doInitialize;
end;

constructor TExpert.Create(param1, param2: string);
begin
  inherited;

  doInitialize;
end;


So hab ich mir das ungefähr vorgestellt 'inkl kommentar'
Jetzt zu meinen offenen fragen..
1. Muss ich bei TAdvance auch die Create(Param1)|Create(Param1,Param2) in der Deklaration angeben. damit die dann von TExpert erkannt werden damit das Kompilieren glückt? Sprich werden die nicht automatisch von TBasic übernommen?
2. Wenn das Compilieren klappt kann ich immer ein Objekt von TExpert erzeugen und zwar mit dem Default Constructor.. (laut intellisense von delphi oder wie das heisst und auch compilieren lässt es sich.. beim debugen hab ich mühe da kommt ne meldung wenn ich mit f7 rein möchet)
sprich ich kann myExpObj := TExpert.Create() ausführen.. aber das sollte nicht gehen..
Ich möchte das nur
myExpObj := TExpert.Create('param1')
myExpObj := TExpert.Create('param1','param2')
funktioniert.

Sprich muss ich da den Defaultconstructor bei TBasic etc irgendwie mit Reintroduce oder sowas betiteln?


Vielen Dank für eure Hilfe.

Gruss Chubbson

Edit: Ahja es handelt sich um Delphi 7 falls das relevant sein sollte
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 25.06.09 13:34 
Es gibt auch noch reintroduce zusätzlich zu overload. ;-)

Mit Compilermeldungen musst du aber leben oder diese ausblenden, denn da wird dann kommen, das das nie benutzt wird, wenn du es unter private schreibst.
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1335
Erhaltene Danke: 118

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Do 25.06.09 14:06 
Wenn du nicht willst das der Constructor verwendet wird, überschreibe ihn und gibt in ihm eine Exception aus.
In dem Text der Exception schreibst du warum der Constructor nicht verwendet werden soll. Denn es ist ja so das nur ein Entwickler diesen einbinden wird, wenn er dann testet weiß er woran er ist und kann es ändern.
Das ist zwar keine super tolle Lösung, aber eine die sich selber erklärt.

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 25.06.09 14:09 
Es geht wie gesagt auch mit reintroduce, wenn der Konstruktor nicht virtuell und damit nicht überschreibbar ist, wie gesagt. Es kommt eben eine Meldung beim Kompilieren, die man aber mit der HINTS-Direktive auch unterdrücken kann.

Vorteil: Man kann den Konstruktor erst gar nicht verwenden.
chubbson Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 32
Erhaltene Danke: 1



BeitragVerfasst: Do 25.06.09 14:44 
Vielen Dank für die antwort. Jaenicke deine lösung musst du mir nochma bissl erläutern.
@Sinspin ja ich möcht eigentlich expliziit das der defaultconstructor ohne parameter bei abgegeleiteten klassen explizit nicht mehr aufgerufen werden kann. ohne Exception.. aber danke für den hinweis.

ich habs nun so gelösst

TBasic
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
TBasic = class(TObject)
    private
      constructor Create(); reintroduceoverload//@Jaenicker hierhinein? habs mal so probiert kann das Objekt immernoch mit Create() erzeugen
    public
      constructor Create(param1: string); overloadvirtual;                 //EIn Objekct muss mit entweder mit 1 Parameter 
      constructor Create(param1: string; param2: string); overloadvirtual//oder 2 Parameter erzeugt weren
end;


TAdvance
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
TAdvance = class( TBasic )
      private
        ;  //Besitzt weder default Create 
      public
        ;  //Noch Create mit params
end;


TExpert
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
TExpert = class( TAdvance )
      private
        procedure doInitialize();
      public
        constructor Create(param1: string); reintroduceoverload;                 // funktioniert, kann constructor mit der basis von TBasic erweitern wie gewünscht
        constructor Create(param1: string; param2: string); reintroduceoverload// funktioniert, kann constructor mit der basis von TBasic erweitern wie gewünscht

end;
....

procedure TExpert.doInitialize;
begin
  //Do Something
end;

constructor TExpert.Create(param1: string);
begin
  inherited;

  doInitialize;
end;

constructor TExpert.Create(param1, param2: string);
begin
  inherited;

  doInitialize;
end;



So ich möcht nun wie gesagt ein Object von TExpert erzeugen.. dafür soll es nicht möglich sein über den defaultconstructor Create() zu gehen. Sondern explizit TExpertCreat('param1','param2')

wie mach ich das genau..
sprich wo erstell ich das Create(); reintroduce;
in welcher klasse? jeweils in allen?
public? privat?

Sie wie iche es jetzt oben stehen habe mit einem Private Constructor Create(); Reintroduce; in TBasic
Kann ich immernoch ein TExpert objekt über TExpert.Create() erzeugen..

Danke füe die hilfe
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 25.06.09 16:14 
Ja, ok, so sollte es aber klappen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
type
  TConstructorObject = class(TObject)
  strict private
  {$HINTS OFF}
    constructor Create(); virtualabstract;
  {$HINTS ON}
  end;

  TBasic = class(TConstructorObject)
  public
    constructor Create(param1: string); overloadvirtual;
    constructor Create(param1: string; param2: string); overloadvirtual;
  end;
Statt strict private kannst du auch nur private oder auch protected schreiben. Da kommen aber Warnmeldungen, weil da das Create erreichbar wäre und dadurch verborgen wird.
Bei private / protected ist der Konstruktor für TBasic erreichbar (bei private in der selben Datei), was schlecht ist, da der abstrakt ist. Aber das wäre ja deine eigene Klasse und strict private gibts erst ab Delphi 2006, vorher ginge es also nur ohne strict.
chubbson Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 32
Erhaltene Danke: 1



BeitragVerfasst: Do 25.06.09 16:56 
Vielen Dank für die Antwort Funktioniert wunderbar.

Ich schreib gerade unter D7 und hab einfach Private genommen..
Reicht völlig aus..
Die Compiler Warnings die dadurch entstehen
"Method 'Create' hides virtual method of base type 'TBasic'"
die stören nich sonderlich..

Nochma danke für die Hilfe, wieder was gelern :zustimm:
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 25.06.09 16:57 
Dann würde ich die Warnungen da einfach ausschalten, das verwirrt den anwendenden Programmierer sonst nur. ;-)
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
type
  TConstructorObject = class(TObject)
  private
  {$HINTS OFF}
    constructor Create(); virtualabstract;
  {$HINTS ON}
  end;

  TBasic = class(TConstructorObject)
  public
  {$WARNINGS OFF}
    constructor Create(param1: string); overloadvirtual;
    constructor Create(param1: string; param2: string); overloadvirtual;
  {$WARNINGS ON}
  end;