2009-07-15 11 views
1

Si j'ai une classe enfant, la classe enfant hérite de toutes les méthodes du parent, mais comment utiliser les fonctions de la classe enfant dans la classe parente? Est-ce cela que l'abstraction est? Comment l'accomplir?Abstraction dans Delphi

Mon code:

type 
cParent = class(TObject) 
private 
    function ParentFunction:byte; 
    function ChildFunction:byte;virtual;abstract; 
end; 

type 
cChild = class(cParent) 
private function ChildFunction:byte;override; 
end; 

function cChild.ChildFunction:byte; 
begin 
    Exit(20); 
end; 

function cParent.ParentFunction:byte; 
begin 
    Exit(10); 
end; 

var 
c:cParent; 

begin 
    c:= cParent.Create; 
    WriteLn(c.ChildFunction); 
    Readln; 
end. 

Il compile le fichier, mais je reçois exception d'abstraction.

+0

Quand vous dites qu'il se compile bien, voulez-vous vraiment dire que vous n'avez * pas * reçu d'avertissement du compilateur vous disant que vous instanciez une classe abstraite? Vous devez être plus diligent à propos de l'éradication des astuces et des avertissements du compilateur, pas seulement des erreurs. –

+0

Juste quelques commentaires concernant le style conventionnel. Il est habituel dans Delphi de préfixer les noms de classe (et autres types) avec T, pas c. La valeur de retour des fonctions est généralement définie en définissant la variable Résultat implicite sur une valeur, plutôt que d'utiliser Quitter, par exemple Résultat: = 10 ;, pas Quitter (10) ;. La syntaxe Exit n'a été ajoutée que dans D2009 Remarque: Vous pouvez également utiliser le nom de la fonction plutôt que le résultat (ParentFunction: = 10;) - l'effet est le même et c'est la syntaxe Pascal originale –

Répondre

5
c:= cParent.Create; 
WriteLn(c.ChildFunction); 

Vous créez une instance de classe cParent ici. Cette classe contient uniquement une ChildFunction abstraite qui peut être surchargée par d'autres classes. La fonction n'est pas implémentée dans cParent, vous obtenez donc une erreur abstraite.

Le code fonctionne si vous utilisez la classe au lieu cChild, où ChildFunction est mis en œuvre:

c:= cChild.Create; 
WriteLn(c.ChildFunction); 

Pour plus de précisions, imaginez une classe parente nommée GeometricObject avec une méthode abstraite virtuelle CalculateVolume. Vous pouvez maintenant créer des classes enfants telles que SphereObject ou BoxObject qui implémentent CalculateVolume en utilisant la formule pour les sphères/boîtes. Mais cela n'a aucun sens de créer une instance de GeometricObject et d'appeler CalculateVolume.

+0

Ok, mais alors quel est le utilisation de mots-clés "virtuels", "abstraits" et "override"? –

+2

"virtuel" signifie que la méthode peut être surchargée par des classes enfants. "abstract" signifie que la méthode n'est pas implémentée par la classe parente, mais peut être implémentée dans les classes enfants. "override", eh bien, remplace les méthodes virtuelles des classes parentes. Toutes les méthodes abstraites doivent être virtuelles, mais les méthodes peuvent être virtuelles sans être abstraites. – schnaader

+0

Les méthodes abstraites sont ce que C++ appelle les méthodes "virtuelles pures". Ils doivent être implémentés dans une classe enfant. –

1

Créer l'instance en utilisant la classe enfant:

c:= cChild.Create; 
2

Vous créez une instance de la classe cParent. Cette classe n'a pas d'implémentation de childFunction. c doit être une instance de la classe cChild. Code correct: c: = cChild.Create; WriteLn (c.FonctionChild);

0

Il me semble que vous avez confondu les relations d'héritage et les relations possessives. Si vous définissez une classe "cChild" comme héritée de la classe "cParent" alors la classe "cChild" est un "cParent", cela ne signifie pas que la classe "Parent" a accès à des classes enfants. La seule façon d'appeler la fonction abstraite "ChildFunction" dans la classe "cParent" provient d'une autre fonction, par ex. "ParentFunction", mais seulement si l'objet lui-même est pas un "cParent":

function cParent.ParentFunction:byte; 
begin 
    Result := ChildFunction * 2; 
end; 

var 
    c:cParent; 

begin 
    c:= cChild.Create; 
    WriteLn(c.ParentFunction); 
    Readln; 
end. 

Ici, puisque c est un cChild, ParentFunction appelle correctement ChildFunction, qui est défini dans cChild.

0

En réponse à schnaader, en ce qui concerne CS 101:

"virtuel" signifie que la méthode peut être substituée par des classes d'enfants.

Non seulement cela, mais les fonctions non virtuelles peuvent heureusement être remplacées par les classes enfants. La différence est très importante: lorsqu'une fonction virtuelle est appelée par la classe parente, la fonction CHILD sera exécutée. Cela permet aux classes enfants d'implémenter des fonctions qui seront appelées par des classes parents sans que le parent ne sache quoi que ce soit à leur sujet. C'est l'essence de polymorphisme.