2010-09-24 5 views
3

Ok, donc j'ai cette classe, disons CMain, qui contient une classe CFruit. Ce que je voudrais faire est d'exécuter des fonctions basées sur le type de CFruit (si c'est CPear ou CApple, etc). Je voudrais donc faire quelque chose comme ceci:Classe parent dans une autre classe

type CMain = class 
    myFruit : CFruit; 
    function GetFruit() : CFruit; 
    procedure SetFruit(Fruit : CFruit); 
end; 

procedure CMain.SetFruit(Fruit : CFruit); 
begin 
    if Fruit.IsPear then .. else etc; 
end; 

... évidemment le compilateur me empêche de faire cela parce que CFruit est juste parent de CPear et Capple. Y a-t-il un moyen viable de le faire? (Il est hors de question que CMain soit séparé). Merci.

+7

vous une faveur et d'utiliser T comme préfixe pour les noms de classe Delphi: 'TMain',' TFruit' etc. –

+1

@Ulrich: Peut-être est une sorte de code source obscurcissement :) – mjn

Répondre

1

Voici un exemple pour l'utilisation de méthodes virtuelles:

type 
TFruit = class 
public 
    procedure doSomethingFruitSpecific; virtual; abstract; 
end; 

TPear = class(TFruit) 
public 
    procedure doSomethingFruitSpecific; override; 
end; 

TApple = class(TFruit) 
public 
    procedure doSomethingFruitSpecific; override; 
end; 

TMain = class 
    procedure SetFruit(Fruit : TFruit); 
end; 

implementation 

procedure TMain.SetFruit(Fruit : TFruit); 
begin 
    Fruit.doSomethingFruitSpecific; 
end; 

procedure TApple.doSomethingFruitSpecific; 
begin 
    Writeln('bake an apple pie'); 
end; 

procedure TPear.doSomethingFruitSpecific; 
begin 
    Writeln('pick some pears'); 
end; 
7

IIUC vous voulez virtual methods.

+0

+1. C'est la bonne réponse. Les méthodes virtuelles utilisent le type de la classe pour appeler la version de la méthode que vous avez définie pour cette classe. –

+0

Exactement! Donc nous ne lui disons pas qu'il y a une construction comme "si le Fruit est CPear alors", n'est-ce pas? –

+0

** I ** ne sera pas. ;-) –

3

En fait, il y a un « est » opérateur, qui vérifiera si l'objet est une instance de classe ou il est ancêtres. Ceci est appelé "vérification de type dynamique" et est en cours de développement. Consultez l'aide pour une clarification.

En fonction de vos besoins, les "méthodes virtuelles" pourraient être ce dont vous avez besoin, comme expliqué par d'autres. S'il vous plaît vérifier le lien posté sur "méthodes virtuelles" comme la bonne méthode OOP.

Dans l'exemple ci-dessous

if AFruit is TApple then 

et

if AFruit is TFruit then 

deux return true

type 
    TFruit = class 
    protected 
    FName: string; 
    public 
    property Name: string read FName; 
    end; 

    TApple = class(TFruit) 
    public 
    constructor Create; 
    end; 

    TPear = class(TFruit) 
    public 
    constructor Create; 
    end; 

    TForm1 = class(TForm) 
    Button1: TButton; 
    mixed: TLabel; 
    procedure Button1Click(Sender: TObject); 
    private 
    { Private declarations } 
    FMixValue: string; 
    procedure MixFruits(AFruit: TFruit); 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    APear: TPear; 
    AApple : TApple; 
begin 
    APear := TPear.Create; 
    AApple := TApple.Create; 
    MixFruits(APear); 
    MixFruits(AApple); 
    mixed.Caption := FMixValue; 
end; 

{ TPear } 

constructor TPear.Create; 
begin 
    inherited; 
    FName := 'Pear'; 
end; 

{ TApple } 

constructor TApple.Create; 
begin 
    inherited; 
    FName := 'Apple'; 
end; 

procedure TForm1.MixFruits(AFruit: TFruit); 
begin 
    FMixValue := FMixValue + ' ' + AFruit.Name; 
    if AFruit is TApple then 
    ShowMessage('An Apple') 
    else if AFruit is TPear then 
    ShowMessage('A Pear') 
    else 
    ShowMessage('What is it?'); 
end; 
+0

+1, car l'utilisation de méthodes virtuelles pour remplacer l'opérateur "is" est mauvaise (ergh, le côté obscur?). Entre autres choses, remplacer "est" par des méthodes virtuelles nécessite que la classe PARENT ait connaissance de chaque classe CHILD qui existera. Si jamais vous commencez à manger des avocats, il ne suffit pas de créer la classe TAvocado, vous devez ajouter une méthode IsAvocado à la classe parente. –

+0

J'ose dire que les méthodes "normales" comme IsAvocado ne sont pas nécessaires et devraient être considérées comme une odeur de code. Bien sûr il y a des exceptions yada yada yada ... :-) –

Questions connexes