Требуется ли вызвать базовый метод при получении из TObject?

У меня есть класс, который спускается с TObject, если я не вызываю родительский метод, это плохо? Я спрашиваю, потому что, смотря на TObject.Create/Destroy, они ничего не делают.

Вот почему мы переопределяем их/сами.

Нет примера кода, я просто хочу убедиться.

Ответ 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, потому что этот вызов ничего не делает.

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

Ответ 2

Вам нужно только позвонить inherited, если вы хотите, чтобы код предков выполнялся. Вам нужен этот код, иногда нет. Вы также можете использовать условные обозначения и вызывать inherited только в том случае, если выполнено какое-либо условие, и вы можете выбрать, когда это сделать (начало метода, конец метода,...).

Следовательно, все зависит от ситуации.

Вот пример.

Ответ 3

Даже если методы TObject Create/Destroy ничего не делают в текущей версии, они могут быть в некоторой будущей версии (маловероятной, но все же возможно). Так это ДОЛЖНО для вас прямо сейчас? Нет, потому что он ничего не добьется, но только потому, что текущий родитель не добавляет никаких функций.

Если вы хотите, чтобы ваши объекты-потомки всегда добавляли функциональность своим родителям, вероятно, было бы хорошей идеей последовательно называть inherited.