当我在基类上调用方法时,如何调用后代的实现? [英] How do I invoke a descendant's implementation when I call a method on a base class?

查看:117
本文介绍了当我在基类上调用方法时,如何调用后代的实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的顶级类是 TBaseDB ,其中有一个后代 TCommonDB (和 TCommonDB 将具有多个后代,例如 TProdDB TDevDB

My top level class is TBaseDB, which has a descendant TCommonDB (, and TCommonDB will have multiple descendants, like TProdDB and TDevDB).

让我们在每个类定义中创建一个名为 Test1 的函数。现在,它所做的只是一个 ShowMessage('Some literal')只是为了告诉我执行什么代码。

Let's create a function in each class definition, called Test1. For now, all it does is a ShowMessage('Some literal') just to show me what code is being executed.

直到运行时,我不知道类类型。我想要有通用的代码,但不同的行为。

I don't know the class type until runtime. I want to have common code, but different behavior.

我想要的是这样的:

var
  MyObj: TBaseDB;
begin        
  //pseudo-code...
  if RadioButton1.Checked then
    MyObj := TBaseDB.Create
  else
    MyObj := TCommonDB.create;
  MyObj.Test1;    
end;

我似乎无法让这个工作,我想象这是在我的类定义。如何定义 Test1 ,以便:

I can't seem to get this to work, and I imagine it is in my class definition. How should Test1 be defined so that:


  1. 我可以将我的变量声明为 TBaseDB

  2. 创建的类可以是 TBaseDB TCommonDB

  3. 正确 测试程序将被调用取决于实例是 TBaseDB TCommonDB

  1. I can declare my variable as TBaseDB,
  2. the created class can be either TBaseDB or TCommonDB, and
  3. the proper Test procedure will be called depending on the instance being a TBaseDB or TCommonDB?


推荐答案

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

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

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

  TOrange = class(TFruit)
  public
    procedure ShowMessage; override;
  end;


{ TApple }

procedure TApple.ShowMessage;
begin
  Writeln('I''m an apple!');
end;

{ TOrange }

procedure TOrange.ShowMessage;
begin
  Writeln('I''m an orange!');
end;

var
  fruit: TFruit;

begin

  fruit := TApple.Create;

  fruit.ShowMessage;

  Writeln('Press Enter to continue.');
  Readln;

end.

关键字 abstract 允许您没有在基类中实现。然而,您也可以在这里实施:

The keyword abstract allows you to have no implementation at all in the base class. You can also, however, have an implementation there as well:

program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  TFruit = class
  public
    procedure ShowMessage; virtual;
  end;

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

  TOrange = class(TFruit)
  public
    procedure ShowMessage; override;
  end;


{ TFruit }

procedure TFruit.ShowMessage;
begin
  Writeln('I''m a fruit.');
end;

{ TApple }

procedure TApple.ShowMessage;
begin
  inherited;
  Writeln('I''m an apple!');
end;

{ TOrange }

procedure TOrange.ShowMessage;
begin
  inherited;
  Writeln('I''m an orange!');
end;

var
  fruit: TFruit;

begin

  fruit := TApple.Create;

  fruit.ShowMessage;

  Writeln('Press Enter to continue.');
  Readln;

end.

练习:


  1. 在每种情况下,如果您创建一个 TFruit 的实例会发生什么?

  2. 在第二种情况下,继承在 TApple.ShowMessage Torange.ShowMessage 是什么意思?他们需要在程序的顶部吗?如果省略它们会发生什么?

  1. In each case, what happens if you create an instance of TFruit?
  2. In the second case, what does inherited in TApple.ShowMessage and TOrange.ShowMessage mean? Do they need to be at the top of the procedures? What happens if you omit them?

这篇关于当我在基类上调用方法时,如何调用后代的实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆