я ищу понять
применительно к конструкторам объектов. Каждый раз, когда я случайным образом добавляю ключевые слова, пока компилятор не закрывается - и (после 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
переопределяет оба конструктора, вызывая унаследованную версию каждого Теперь этот код не компилируется. я хочу понять , почему это не работает. Я также хочу понять, как правильно переопределять конструкторы. Или, может быть, вы никогда не сможете переопределить конструкторы? Или, может быть, переопределение конструкторов вполне приемлемо? Возможно, вам никогда не следует иметь несколько конструкторов, возможно, вполне приемлемо иметь несколько конструкторов.
Я хочу понять почему . Тогда исправить это было бы очевидно.
Изменить: Я тоже хотят получить некоторые рассуждения о порядке виртуального
, переопределения
, перегрузки
, повторного введения
.Потому что при попытке всех комбинаций ключевых слов количество комбинаций резко возрастает:
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;