好的,所以我有这个课,让我们说CMain,包含一个CFruit课程。我想要做的是运行基于CFruit类型的函数(如果它是CPear或CApple等)。所以我想做这样的事情:
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;
......显然编译器阻止我这样做,因为CFruit只是CPear和CApple的父母。有什么可行的方法可以做到这一点吗? (制作海滩上的CMain是不可能的)。感谢。
答案 0 :(得分:7)
你想要的IIUC virtual methods。
答案 1 :(得分:3)
实际上有一个“是”运算符,它将检查Object是类的实例还是它的祖先。这称为“动态类型检查”,并且是高级的。请查看帮助以获得说明。
根据您的需要,“虚拟方法”可能是您需要的,正如其他人所解释的那样。请检查发布的关于“虚拟方法”的链接作为正确的OOP方式。
在下面的例子中
if AFruit is TApple then
和
if AFruit is TFruit then
都返回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;
答案 2 :(得分:1)
以下是使用虚拟方法的示例:
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;