Помощник класса не переопределяет виртуальные методы предка - PullRequest
3 голосов
/ 13 марта 2019

Я всегда понимал помощников классов как классы расширения или частичные классы. Они действуют как расширение для кода исходного базового класса. Если я скопирую интерфейсную часть кода и добавлю ее в базовый класс, а также сделаю это для реализации, код будет работать точно так же, как и с помощником. Это позволило мне всегда понимать полиморфизм в помощниках и почему они не могут переопределять методы из базового класса и тому подобное.

Но я обнаружил, что это не совсем так, потому что если это так, то почему они не позволяют переопределить методы родителя-предка базового класса?

Вот пример того, что я имею в виду (я приведу код только для заголовков без кода реализации):

type
  TAncestor = class
  public 
    procedure Test; virtual;
  end;

  TBase = class(TAncestor)
  public 
  end;

Так почему следующий код неверен:

THelper = class helper of TBase
public 
  procedure Test; override;
end;

У меня ошибка:

Метод «Тест» не найден в базовом классе!

1 Ответ

9 голосов
/ 13 марта 2019

Помощники классов не могут изменять исходную раскладку классов. Вот почему они не могут добавлять поля (но, конечно, могут добавлять не виртуальные, не динамические методы). Дополнительные методы на самом деле не являются частью класса help, они просто сообщают компилятору, что каждый раз, когда он видит этот метод, он должен притворяться , что он был частью исходного класса

Но переопределение виртуального метода означало бы изменение таблицы виртуальных методов помогаемого класса, что также невозможно. Конечно, компилятор может создать новый VMT (массив указателей на код) с переопределением в нем, но, поскольку помощник класса не изменяет «помогший» экземпляр, он не может просто заменить указатель VMT в экземпляре. с новым. Таким образом, невозможно создать экземпляр для ссылки на новый VMT.

Существует только один способ переопределить виртуальный метод: наследование.

Документация говорит:

Вспомогательный тип может не объявлять данные экземпляра, но поля класса разрешены.

...