Delphi: понимание конструкторов

я ищу понять

  • виртуальное
  • переопределить
  • overloa d
  • повторно ввести

применительно к конструкторам объектов. Каждый раз, когда я случайным образом добавляю ключевые слова, пока компилятор не закрывается - и (после 12 лет разработки с Delphi) я предпочитаю знать, что я делаю, а не пробовать что-то наугад.

Учитывая гипотетический набор объектов:

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

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

TiPhone = class(TCellPhone)
public
    constructor Create(Cup: Integer); override;
    constructor Create(Cup: Integer; Teapot: string); override;
end;

То, как я хочу, чтобы они вели себя, вероятно, очевидно из объявлений, но:

  • TComputer имеет простой конструктор, и потомки могут его переопределить
  • TCellPhone имеет альтернативный конструктор, и потомки могут его переопределить
  • TiPhone переопределяет оба конструктора, вызывая унаследованную версию каждого

Теперь этот код не компилируется. я хочу понять , почему это не работает. Я также хочу понять, как правильно переопределять конструкторы. Или, может быть, вы никогда не сможете переопределить конструкторы? Или, может быть, переопределение конструкторов вполне приемлемо? Возможно, вам никогда не следует иметь несколько конструкторов, возможно, вполне приемлемо иметь несколько конструкторов.

Я хочу понять почему . Тогда исправить это было бы очевидно.

См. Также

Изменить: Я тоже хотят получить некоторые рассуждения о порядке виртуального , переопределения , перегрузки , повторного введения .Потому что при попытке всех комбинаций ключевых слов количество комбинаций резко возрастает:

  • виртуальные; перегрузка;
  • виртуальный; переопределить;
  • переопределить; перегрузка;
  • переопределение; виртуальный;
  • виртуальный; переопределить; перегрузка;
  • виртуальный; перегрузка; переопределение;
  • перегрузка; виртуальный; переопределить;
  • переопределить; виртуальный; перегрузка;
  • переопределение; перегрузка; виртуальный;
  • перегрузка; переопределить; virtual;
  • etc

Edit 2: я думаю, мы должны начать с " возможна ли иерархия объектов? " Если нет, то почему бы и нет? Например, является ли принципиально неправильным иметь конструктор от предка?

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

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

Я ожидаю, что TCellPhone теперь имеет два конструктора. Но я не могу найти комбинацию ключевых слов в Delphi, чтобы заставить его думать, что это действительно так. Я в корне ошибаюсь, думая, что у меня может быть два конструктора здесь, в TCellPhone ?


Примечание: Все, что находится под этой строкой, не является строго необходимым для ответа на вопрос - но это имеет помогите объяснить мои мысли. Возможно, вы поймете, основываясь на моем мыслительном процессе, какой фундаментальный элемент, который мне не хватает, все проясняет.

Теперь эти объявления не компилируются:

//Method Create hides virtual method of base type TComputer:
TCellPhone = class(TComputer)
   constructor Create(Cup: Integer; Teapot: string);  virtual;

//Method Create hides virtual method of base type TCellPhone:
TiPhone = class(TCellPhone)
public
   constructor Create(Cup: Integer); override;
   constructor Create(Cup: Integer; Teapot: string); overload;  <--------
end;

Итак, сначала я попробую исправить TCellPhone . Я начну с случайного добавления ключевого слова overload (я знаю, что не хочу повторно вводить , потому что это скроет другой конструктор, который мне не нужен):

TCellPhone = class(TComputer)
public
   constructor Create(Cup: Integer; Teapot: string); virtual; overload;
end;

Но это не удается: Определение поля не допускается после методов или свойств .

Я знаю по опыту, что, даже если у меня нет поля после метода или свойства, если я изменю порядок ключевых слов virtual и overload : Delphi будет Заткнись:

TCellPhone = class(TComputer)
public
   constructor Create(Cup: Integer; Teapot: string); overload; virtual; 
end;

Но я все равно получаю сообщение об ошибке:

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

Поэтому я пытаюсь удалить оба ключевых слова:

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

Но я все равно получаю сообщение об ошибке:

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

Так что я смиряюсь с попыткой повторно ввести :

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

И теперь TCellPhone компилируется, но для TiPhone стало намного хуже. :

TiPhone = class(TCellPhone)
public
   constructor Create(Cup: Integer); override; <-----cannot override a static method
   constructor Create(Cup: Integer; Teapot: string); override; <-----cannot override a static method
end;

Оба жалуются, что я не могу их переопределить, поэтому я удаляю ключевое слово override :

TiPhone = class(TCellPhone)
public
   constructor Create(Cup: Integer);
   constructor Create(Cup: Integer; Teapot: string);
end;

Но теперь второе создание говорит, что оно должно быть помечено перегрузкой, что я и делаю (на самом деле я ' Я помечу их как перегрузку, так как я знаю, что будет, если я этого не сделаю):

TiPhone = class(TCellPhone)
public
   constructor Create(Cup: Integer); overload;
   constructor Create(Cup: Integer; Teapot: string); overload;
end;

В разделе interface все хорошо. К сожалению, мои реализации не работают.Мой конструктор единственного параметра TiPhone не может вызвать унаследованный конструктор:

constructor TiPhone.Create(Cup: Integer);
begin
    inherited Create(Cup); <---- Not enough actual parameters
end;
34
задан Community 23 May 2017 в 12:33
поделиться