Ответ 1
Наиболее распространенное поведение - вызов inherited
. Поэтому, если я явно не хочу унаследованного поведения, я не называю inherited
. В противном случае, я знаю. Если унаследованное поведение является no-op вроде TObject.Create/Destroy
, я все равно вызываю inherited
.
Обратите также внимание на то, что сидение для конструкторов и деструкторов, возможно, немного отличается от других методов. Это очень редко, что вам нужно будет пропустить вызов унаследованного метода. Я не могу придумать пример. Неизбежно конструкторы создают и уничтожают другие объекты, поэтому как вы могли сочтет это пропуском?
Я знаю, что некоторые авторы пишут код, который опускает inherited
при получении непосредственно из TObject
, потому что они знают, что реализация в TObject
ничего не делает. Мне это не нравится, и для меня это ошибка. Детали реализации TObject
не должны протекать в производные классы.
Я уверен, что TObject.Create/Destroy
всегда будет no-ops. Если бы Embarcadero изменился, тогда столько кода сломалось бы. Но как насчет одного из ваших классов. Предположим, что у вас есть класс, полученный из TObject
. И тогда у вас есть другой класс, полученный из этого:
TMyClass1 = class
....
end;
TMyClass2 = class(TMyClass)
....
end;
У вас нет конструктора для TMyClass1
и конструктора для TMyClass2
, который выглядит так:
constructor TMyClass2.Create;
begin
// no need to call inherited, it a no-op
FMyObj := TBlahBlah.Create;
end;
Затем в один прекрасный день вы модифицируете конструктор TMyClass1
, чтобы что-то сделать. Теперь TClass2
сломан. Поэтому я никогда бы не опустил вызов inherited
, потому что этот вызов ничего не делает.
Ситуация для обычных методов экземпляра немного отличается. Более правдоподобно, что вы хотите игнорировать реализацию базового класса и обеспечить совершенно новую реализацию. Но принимайте решение, основанное на том, что хочет сделать производный класс, а не в том, имеет ли суперкласс для пустых реализаций метода.