я ищу понять
- виртуальный
- переопределить
- перегрузить
- повторно ввести
при применении к конструкторам объектов.Каждый раз, когда я случайным образом добавляю ключевые слова до тех пор, пока компилятор не отключится - и (после 12 лет разработки с Delphi) я предпочел бы знать, что я делаю, а не пытаться делать что-то случайным образом.objects:
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
переопределяет оба конструктора, вызывая унаследованную версию каждого
Теперь этот код нене компилировать.Я хочу понять , почему это не работает.Я также хочу понять, как правильно переопределить конструкторы.Или, возможно, вы никогда не сможете переопределить конструкторы?Или, возможно, вполне приемлемо переопределить конструкторы?Возможно, вам никогда не следует иметь несколько конструкторов, возможно, вполне допустимо иметь несколько конструкторов.
Я хочу понять, почему 1038 *.Исправление было бы тогда очевидным.
См. Также
Редактировать: Я также ищучтобы получить некоторые рассуждения порядка virtual
, override
, overload
, reintroduce
.Потому что при попытке всех комбинаций ключевых слов количество комбинаций взрывается:
- virtual;перегрузка;
- виртуальная;переопределить;
- переопределить;перегрузка;
- переопределение;виртуальный;
- виртуальный;переопределить;перегрузка;
- виртуальная;перегрузки;переопределение;
- перегрузка;виртуальный;переопределить;
- переопределить;виртуальный;перегрузка;
- переопределение;перегрузки;виртуальный;
- перегрузка;переопределить;виртуальный;
- и т. д.
Редактировать 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
(я знаю, что не хочу reintroduce
, потому что это скрыло бы другой конструктор, который мне не нужен):
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer; Teapot: string); virtual; overload;
end;
Но этотерпит неудачу: Field definition not allowed after methods or properties
.
из опыта я знаю, что, даже если у меня нет поля после метода или свойства, если я переверну порядок ключевых слов 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'
Так что я смиряюсь с попыткой reintroduce
:
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;
Но теперь 2-е создание говорит, что оно должно быть помечено перегрузкой, что я и делаю (на самом деле я помечу оба как перегрузку, так как я знаю, что произойдет, если я не буду):
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;