从子类调用方法时出现“抽象错误”

Tom*_*Tom 1 delphi

我想根据参数实例化类。这两个类都是从 TSample 派生的,所以我将我的代码定义为:

var T: TSample;
Run Code Online (Sandbox Code Playgroud)

然后我做

T := TMySample.Create; 
Run Code Online (Sandbox Code Playgroud)

或者

T := TYourSample.Create;
Run Code Online (Sandbox Code Playgroud)

并调用T.Hello给出了“抽象错误”。

type TSample = class
     public
       procedure Hello; virtual; abstract;
     end;

     TMySample = class(TSample)
     public
       procedure Hello;
     end;

     TYourSample = class(TSample)
     public
       procedure Hello;
     end;

...

procedure TForm1.Button1Click(Sender: TObject);
var T: TSample;
    a: Integer;
begin
  if a = 1 then T := TMySample.Create
  else          T := TYourSample.Create;

  T.Hello;      //Abstract Error here
  T.Free;
end;

procedure TMySample.Hello;
begin
  showmessage('My');
end;

procedure TYourSample.Hello;
begin
  showmessage('Your');
end;
Run Code Online (Sandbox Code Playgroud)

And*_*and 5

您忘记将重写的方法声明为重写:

 TMySample = class(TSample)
 public
   procedure Hello; override; // <--
 end;

 TYourSample = class(TSample)
 public
   procedure Hello; override; // <--
 end;
Run Code Online (Sandbox Code Playgroud)

实际上,编译器警告过您这一点,但您没有听:)

[dcc32 Warning] Unit1.pas(25): W1010 Method 'Hello' hides virtual method of base type 'TSample'
[dcc32 Warning] Unit1.pas(30): W1010 Method 'Hello' hides virtual method of base type 'TSample'
Run Code Online (Sandbox Code Playgroud)

此外,您可能已经知道这一点,但是您的示例代码存在两个问题:

  1. 由于非托管类型的局部变量未初始化,因此 的值a未定义。
  2. 你不保护TSample对象,所以你可能会泄漏资源。(实际上,在这种情况下,您将由于异常!)

固定的:

  a := 123;
  if a = 1 then
    T := TMySample.Create
  else
    T := TYourSample.Create;

  try
    T.Hello;      //Abstract Error here
  finally
    T.Free;
  end;
Run Code Online (Sandbox Code Playgroud)