Frage

  

Update: die Frage mit einem einfacheren Beispiel entkernte, die nicht beantwortet wird   von der ursprünglich akzeptierten Antwort

In Anbetracht der folgenden Klasse und ihre Vorfahren:

TComputer = class(TObject)
public
   constructor Create(Teapot: string='');
end;

TCellPhone = class(TComputer)
public
   constructor Create(Cup: Integer); overload; virtual;
   constructor Create(Cup: Integer; Teapot: string); overload; virtual;
end;

Im Moment TCellPhone hat 3 Konstrukteurs sichtbar:

  • Cup: Integer
  • Cup: Integer; Teekanne: string
  • Teekanne: string = ''

Was tun i TCellPhone so dass der Vorfahr Konstruktor (Teapot: string = '') nicht sichtbar ist, so dass nur die deklarierten Konstruktoren:

  • Cup: Integer
  • Cup: Integer; Teekanne: string
  

Hinweis : Normalerweise ist der einfache Akt der mit ein Nachkomme Konstruktor Häuten der Vorfahr:

TCellPhone = class(TComputer)
public
   constructor Create(Cup: Integer); virtual;
end;
     
      
  • Cup: Integer
  •   
     

Und wenn Sie gesucht beide halten die   Vorfahr Konstruktor und die   Nachkomme, würden Sie die Markierung   Abkömmling als overload:

TCellPhone = class(TComputer)
public
   constructor Create(Cup: Integer); overload; virtual;
end;
     
      
  • Cup: Integer
  •   
  • Teekanne: string = ''
  •   

In diesem Beispiel Code Frage ist Delphi meiner overload Schlüsselwörter zu verkennen:

TCellPhone = class(TComputer)
public
   constructor Create(Cup: Integer); overload; virtual;
   constructor Create(Cup: Integer; Teapot: string); overload; virtual;
end;

denken, dass:

  • Ich möchte meine Konstrukteure, um eine Überlastung mit der Vorfahren ,
  • wenn ich wirklich will es, um eine Überlastung der Geschwister

Wie blende ich die Vorfahren Konstruktor?

Hinweis: Es könnte unmöglich sein, die Vorfahren, nicht-virtuellen zu verstecken, Konstruktor mit der Sprache Delphi, wie sie derzeit definiert ist. "Nicht möglich" ist eine gültige Antwort.


Versuchte Antwort (nicht)

i versucht, Markieren den Nachkommen Bauer mit reintroduce (fallen zurück in meinen Modus zufällig das Hinzufügen von Keywords, bis es funktioniert):

TCellPhone = class(TComputer)
public
   constructor Create(Cup: Integer); reintroduce; overload; virtual;
   constructor Create(Cup: Integer; Teapot: string); reintroduce; overload; virtual;
end;

Aber das funktionierte nicht, alle drei Konstrukteure sind noch sichtbar. : (


Original Frage

ich habe ein Objekt, das von einer Klasse, die Konstrukteuren hat nicht wollen, um zu sehen:

TEniac = class(TObject)
   constructor Create(PowerCord: TPowerCord=nil); //calls inherited Create

TComputer = class(TEniac) ...
   constructor Create(PowerCord: TPowerCord=nil); //calls inherited Create(nil)

TCellPhone = class(TComputer)
   constructor Create(sim: TSimChip; UnlockCode: Integer); //calls inherited Create(nil)

TiPhone = class(TCellPhone)
   constructor Create(sim: TSimChip); //calls inherited Create(sim, 0)
  

Hinweis: Dies ist ein hypothetisches Beispiel. Wie in der realen Welt können die Vorfahren Objekte nicht ohne brechen vorhandenen Code geändert werden.

Nun, wenn jemand mit TiPhone ich will sie nicht einmal in der Lage zu sehen der Konstruktor von TEniac:

iphone := TiPhone.Create(powerCord);

Schlimmer noch: Wenn sie diesen Konstruktor aufrufen, sie meinen Konstruktor vollständig vermissen, und alles dazwischen getan. Es ist ziemlich einfach die falsche Konstruktor aufzurufen, alle von ihnen in der IDE-Code-Completion sichtbar sind, und kompiliert:

TiPhone.Create;

und sie ein völlig ungültiges Objekt erhalten.

ich kann TCellPhone ändern, um eine Ausnahme in den Konstrukteuren zu werfen:

TCellPhone.Create(PowerCord: TPowercord)
begin
   raise Exception.Create('Don''t use.');
end;

Doch die Entwickler werden nicht merken, dass sie den falschen Konstruktor aufrufen, bis der Kunde den Fehler an einem Tag und Bußgelder uns bazillions Dollar findet. In der Tat, ich bin versuchen finden überall ich den falschen Konstruktor aufrufen - aber ich kann nicht herausfinden, wie ich machen Delphi sagen

War es hilfreich?

Lösung

Es ist unmöglich, jemals einen Erbauer in einem Vorfahren unzugänglich für die Schaffung einer abgeleiteten Klasse in Delphi eingeführt, weil Sie diese immer tun:

type
  TComputerClass = class of TComputer;

var
  CellPhoneClass: TComputerClass = TCellPhone;
  CellPhone : TCellPhone;
begin
  CellPhone := CellPhoneClass.Create('FUBAR') as TCellPhone;
end;

Nichts, was Sie in dem Code jeder abgeleiteten Klasse tun konnten, jemals jemanden zu verhindern, wäre in der Lage, die TComputer.Create Konstruktor von Aufrufen für eine Instanz der abgeleiteten Klasse zu schaffen.

Das Beste, was Sie tun können, ist:

TComputer = class(TObject)
public
   constructor Create(Teapot: string=''); virtual;
end;

TCellPhone = class(TComputer)
public
   constructor Create(Teapot: string=''); overload; override;
   constructor Create(Cup: Integer); overload; virtual;
   constructor Create(Cup: Integer; Teapot: string); overload; virtual;
end;

In diesem Fall wird der Code oben wäre zumindest Aufruf TCellPhone.Create(Teapot: string='') statt TComputer.Create(Teapot: string='')

Andere Tipps

Wenn ich mich richtig erinnere, dann reintroduce sollten für virtuellen helfen Methoden.

  

Die reintroduce Richtlinie unterdrückt Compiler-Warnungen über versteckte virtuelle Methoden zuvor erklärt.   Verwenden Sie reintroduce, wenn Sie eine geerbte virtuelle Methode mit einer neuen ausblenden möchten.

Ihre aktualisierte Frage zu beantworten - ich denke, es ist nicht ein nicht-virtuellen Konstruktor mit Überlastung in einem direkt abgeleiteten Klasse zu verstecken ist possbile, aber ich habe versucht die folgenden erfolgreich:

TComputer = class(TObject)
public
  constructor Create(Teapot: string='');
end;

TIndermediateComputer = class(TComputer)
protected
  // hide the constructor
  constructor Create;
end;

TCellPhone = class(TIndermediateComputer)
public
   constructor Create(Cup: Integer); overload; virtual;
   constructor Create(Cup: Integer; Teapot: string); overload; virtual;
end;

Sie können nicht die übergeordnete Klasse Konstruktor verstecken, es sei denn es wurde virtuell oder dynamisch erklärt. Sie können es aber verhindern, dass von der untergeordneten Klasse aufgerufen wird. Betrachten Sie Ihr Beispiel:

TComputer = class(TObject)
public
   constructor Create(Teapot: string='');
end;

TCellPhone = class(TComputer)
public
   constructor Create(Cup: Integer); overload; virtual;
   constructor Create(Cup: Integer; Teapot: string); overload; virtual;
end;

TComputer.Create wird von TCellPhone immer sichtbar sein. Sie können TComputer.Create von vermeiden, dass durch die Deklaration einer TCellPhone.Create mit derselben Signatur genannt zu werden.

TCellPhone = class(TComputer)
public
   constructor Create(Teapot: string='');
   constructor Create(Cup: Integer); overload; virtual;
   constructor Create(Cup: Integer; Teapot: string); overload; virtual;
end;

Dann solange man Sie inherited einen Anruf nicht zu TCellPhone.Create(Teapot: string='') im Körper von TComputer.Create haben sich von genannt in TCellPhone und seine Nachkommen verhindern. In dem folgenden:

TCellphone.Create;
TCellphone.Create('MyPhone');

Wird auf TCellPhone Implementierung lösen.

Zusätzlich:

TiPhone = class(TCellPhone)
    constructor Create;
end;

constructor TiPhone.Create;
begin
  inherited;
end;

Wird TCellPhone.Create aufrufen und nicht TComputer.Create.

Statt nur zu heben eine, Ausnahme in den überschriebenen ungültigen Konstrukteuren „Do not verwenden“ betrachten markiert sie deprecated in der Klasse, wo sie ungültig. Das sollte schön Compiler-Warnungen erzeugen, wenn diese ungültigen Konstrukteuren erroneosly verwendet werden.

TCellPhone = class(TComputer)
   constructor Create(PowerCord: TPowerCord=nil); deprecated;
   constructor Create(sim: TSimChip; UnlockCode: Integer); //calls inherited Create(nil)

Darüber hinaus Verwendung Überschreibung oder reintroduce nach Bedarf.

Sie wollen den Konstruktor wieder einführen:

TiPhone = class(TCellPhone)
    constructor Create(sim: TSimChip); reintroduce;

Siehe TComponent.Create in dem Delphi-Quellcode für ein reales Beispiel dafür.

Ich weiß, dass dies ist 5 Jahre alt Thema, aber immer noch kann es jemanden helfen. Der einzige Weg, die Vorfahren Konstruktor zu verstecken ist eine umbenennen der beide erstellen Methoden, um etwas anderes, und entfernen Sie die Notwendigkeit von Überlastung Richtlinie. Es sieht komisch, aber es ist der einzige Weg. Zumindest in älteren Versionen von Delphi. Ich weiß nicht, ist es möglich, jetzt in der XE-Versionen xxx.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top