«Абстрактная ошибка» появляется при вызове методов из дочерних классов - PullRequest
1 голос
/ 15 февраля 2020

Я хочу создать классы на основе параметра. Оба класса являются производными от TSample, поэтому я определяю свой код следующим образом:

var T: TSample;

, затем я делаю

T := TMySample.Create; 

или

T := TYourSample.Create;

, и вызов 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;

1 Ответ

5 голосов
/ 15 февраля 2020

Вы забыли объявить переопределенные методы как, ну, переопределенные:

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

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

На самом деле, компилятор предупреждал вас об этом, но вы не слушали:)

[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'

Кроме того, вы, вероятно, уже знаете это, но есть две проблемы с вашим примером кода:

  1. Поскольку локальные переменные неуправляемых типов не инициализируются, значение a равно undefined.
  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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...