Parent class inside another class
Okay, so I have this class, let's say CMain, that contains a CFruit class. What I would like to do is run functions based on CFruit's type (if it's开发者_如何学运维 CPear or CApple, etc). So I'd like to do something like this:
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;
...obviously the compiler stops me from doing this because CFruit is just CPear and CApple's parent. Is there any viable way I can do this? (making sepparate CMain's is out of the question). Thanks.
IIUC you want virtual methods.
Actually there is an "is" operator, that will check if the Object is an instance of class or it's ancestors. This is called "dynamic type checking" and is sorta advanced. Check the help for a clarification.
Depending on your needs "virtual methods" could be what you need as explained by others. Please check the link posted about "virtual methods" as the correct OOP way.
In the example below
if AFruit is TApple then
and
if AFruit is TFruit then
both 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;
Here is an example for the use of virtual methods:
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;
精彩评论