Visibilité constructeur compréhension
-
28-09-2019 - |
Question
Voici deux classes simples, ont d'abord deux pas des mots-clés (virtuel, surcharge, remplacement, Réintroduction):
TComputer = class(TObject)
public
constructor Create(Teapot: Integer);
end;
TCellPhone = class(TComputer)
public
constructor Create(Teapot: Integer; Handle: string);
end;
i représentera ces DEFINITIONS ci-dessus comme légèrement plus courte:
TComputer = class(TObject)
constructor Create(Teapot: Integer);
TCellPhone = class(TComputer)
constructor Create(Teapot: Integer; Handle: string);
Et lors de la construction TCellPhone
il n'y a qu'un seul constructeur (int
, string
) - parce que le constructeur ancêtre a été caché. je vais indiquer les constructeurs visibles de TCellPhone
comme:
- Teapot: Integer; Poignée: string
Maintenant, pour la question, les 3 premiers cas de sens, le 4 ne fait pas:
1. Ancêtre constructeur est caché par descendant:
TComputer = class(TObject)
constructor Create(Teapot: Integer);
TCellPhone = class(TComputer)
constructor Create(Teapot: Integer; Handle: string);
-
Teapot: Integer; Handle: string
Cela est logique, le constructeur ancêtre est caché parce que je l'ai déclaré un nouveau constructeur.
2. Ancêtre constructeur virtuel est caché par descendant:
TComputer = class(TObject)
constructor Create(Teapot: Integer); virtual;
TCellPhone = class(TComputer)
constructor Create(Teapot: Integer; Handle: string);
-
Teapot: Integer; Handle: string
Cela est logique, le constructeur ancêtre est caché parce que je l'ai déclaré un nouveau constructeur.
Remarque: Parce que l'ancêtre est virtuel: Delphi vous avertit que vous cachez l'ancêtre virtuel (en l'exemple précédent de cacher une constructeur statique: soins de personne, si pas d'avertissement). L'avertissement peut être supprimé (ce qui signifie « Ouais ouais ouais, Je me cache un constructeur virtuel. je signifie pour le faire ") en ajoutant reintroduce .
TComputer = class(TObject) constructor Create(Teapot: Integer); virtual; TCellPhone = class(TComputer) constructor Create(Teapot: Integer; Handle: string); reintroduce;
3. Ancêtre constructeur ne se cache pas dans le descendant en raison de la surcharge:
TComputer = class(TObject)
constructor Create(Teapot: Integer);
TCellPhone = class(TComputer)
constructor Create(Teapot: Integer; Handle: string); overload;
-
Teapot: Integer; Handle: string
-
Teapot: Integer
Cela est logique, puisque le constructeur descendant est une surcharge de l'ancêtre, si les deux sont autorisés à être présents. Le constructeur ancêtre n'est pas caché.
4. constructeur ancêtre virtuel ne se cache pas dans descendant, car la surcharge - mais un avertissement :
Ceci est le cas qui n'a pas de sens:
TComputer = class(TObject)
constructor Create(Teapot: Integer); virtual;
TCellPhone = class(TComputer)
constructor Create(Teapot: Integer; Handle: string); overload;
-
Teapot: Integer; Handle: string
-
Teapot: Integer
Méthode 'Créer' peaux méthode virtuelle de la base de type 'TComputer'
Cela n'a guère de sens. Non seulement est l'ancêtre pas caché, le descendant est surchargé; il ne devrait même pas ' de se plaindre.
Ce qui donne?
La solution
documentation de Delphi dit:
Si vous surchargez une méthode virtuelle, l'utilisation la directive reintroduce lorsque vous redéclarer dans les classes descendantes. Par exemple,
type T1 = class(TObject) procedure Test(I: Integer); overload; virtual; end; T2 = class(T1) procedure Test(S: string); reintroduce; overload; end;
Sans la directive reintroduce, il fonctionne toujours, comme vous l'avez remarqué, mais vous obtenez l'avertissement.
En outre, vous êtes en train de cacher TObject.Create, mais il n'a rien à voir avec l'avertissement. Si vous pensez que vous pouvez accéder à TObject.Create aussi, faites ceci:
type
TComputer = class(TObject)
constructor Create(Teapot: Integer); reintroduce; overload; virtual;
end;
type
TCellPhone = class(TComputer)
constructor Create(Teapot: Integer; Handle: String); reintroduce; overload;
end;
Autres conseils
Je suis d'accord avec la Trinité. La logique derrière l'avertissement semble probablement seulement à déterminer si la méthode de l'ancêtre est dynamique virtuelle / et si un procédé descendant est marqué comme prioritaire ou réintroduire.
Cela vaut également pour les méthodes « normales » aussi bien.
Il peut être supprimé en mettant reintroduce
avant que le modificateur de overload
ou en ajoutant un constructeur à la classe surchargée descendant que simplement les délégués au constructeur ancêtre.
Je l'ai déjà remarqué. L'avertissement est un bug, pour autant que je peux dire, parce que la méthode héritée n'est pas caché. Doit être signalé à qc.embarcadero.com, si elle est pas déjà.