Понимание видимости конструктора - PullRequest
6 голосов
/ 08 октября 2010

Вот два простых класса, изначально у обоих нет ключевых слов (виртуальный, перегрузка, переопределение, повторное введение):

TComputer = class(TObject)
public
   constructor Create(Teapot: Integer);
end;

TCellPhone = class(TComputer)
public
   constructor Create(Teapot: Integer; Handle: string);
end;

Я буду представлять эти определения как несколько более короткие:

TComputer = class(TObject)
   constructor Create(Teapot: Integer);

TCellPhone = class(TComputer)
   constructor Create(Teapot: Integer; Handle: string);

И при построении TCellPhone существует только один конструктор (int, string) - потому что конструктор предка был скрыт.я укажу видимые конструкторы TCellPhone как:

  • Teapot: Integer;Дескриптор: строка

Теперь для вопроса, первые 3 случая имеют смысл, в 4-м нет:

1.Конструктор предка скрыт потомком:

TComputer = class(TObject)
   constructor Create(Teapot: Integer);

TCellPhone = class(TComputer)
   constructor Create(Teapot: Integer; Handle: string);
  • Teapot: Integer; Handle: string

Это имеет смысл, конструктор предка скрыт, потому что я объявил новый конструктор.

2.Виртуальный конструктор-предок скрыт потомком:

TComputer = class(TObject)
   constructor Create(Teapot: Integer); virtual;

TCellPhone = class(TComputer)
   constructor Create(Teapot: Integer; Handle: string);
  • Teapot: Integer; Handle: string

Это имеет смысл, конструктор-предок скрыт, потому что я объявил новый конструктор.

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

    TComputer = class(TObject)
       constructor Create(Teapot: Integer); virtual;

    TCellPhone = class(TComputer)
       constructor Create(Teapot: Integer; Handle: string); reintroduce;

3.Конструктор предка не скрыт в потомке из-за перегрузки:

TComputer = class(TObject)
   constructor Create(Teapot: Integer);

TCellPhone = class(TComputer)
   constructor Create(Teapot: Integer; Handle: string); overload;
  • Teapot: Integer; Handle: string
  • Teapot: Integer

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

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

Это случай, который не имеет смысла:

TComputer = class(TObject)
   constructor Create(Teapot: Integer); virtual;

TCellPhone = class(TComputer)
   constructor Create(Teapot: Integer; Handle: string); overload;
  • Teapot: Integer; Handle: string
  • Teapot: Integer

    Метод «Создать» скрывает виртуальный метод базового типа «TComputer»

Это имеет мало смысла.Не только предок не скрыт, потомок перегружен;это не должно даже быть жаловаться.

Что дает?

Ответы [ 3 ]

5 голосов
/ 09 октября 2010

Документация Delphi гласит:

Если вы перегружаете виртуальный метод, используйте директива вновь, когда вы переопределить его в классах потомков. Например,

type
  T1 = class(TObject)
    procedure Test(I: Integer); overload; virtual;
  end;
  T2 = class(T1)
    procedure Test(S: string); reintroduce; overload;
  end;

Без указания на повторное введение, как вы заметили, она все еще работает, но вы получите предупреждение.

Кроме того, вы на самом деле скрываете объект TObject.Create, но он не имеет ничего общего с предупреждением. Если вы считаете, что вам может потребоваться доступ к TObject.Create, сделайте следующее:

type
  TComputer = class(TObject)
    constructor Create(Teapot: Integer); reintroduce; overload; virtual;
  end;

type
  TCellPhone = class(TComputer)
    constructor Create(Teapot: Integer; Handle: String); reintroduce; overload;
  end;
2 голосов
/ 08 октября 2010

Я бы согласился с Тринидадом.Логика, стоящая за предупреждением, вероятно, только смотрит на то, является ли метод предка виртуальным / динамическим и помечен ли метод-потомок как переопределение или повторное введение.

Это также относится и к "обычным" методам.

Его можно подавить, поместив reintroduce перед модификатором overload или добавив переопределенный конструктор к классу-потомку, который просто делегирует конструктор предка.

1 голос
/ 08 октября 2010

Я уже это заметил. Насколько я могу судить, предупреждение является ошибкой, поскольку унаследованный метод не скрыт. Об этом следует сообщить на qc.embarcadero.com, если это еще не сделано.

...