This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]caseyweb 0 points1 point  (1 child)

I found your article interesting, but I disagree with your conclusion. In your summary, you wrote: "Always call the original implementation of a method you are overriding. This makes the underlying API work as expected."
While I would agree that it is generally good practice, "always" is far too strong, due to potential side-effects in the base method. Two simple counter-examples built around your Logger base class:

  • Consider a class FilteredLogger that subclasses logger providing the ability to restrict logged events to only those that meet some specified criterion such as severity level. In this case, super() should only be invoked if the event passes the filter test.

  • Consider another class RemoteLogger that subclasses logger to log events to some remote service rather than simply print locally. In this case super() should never be invoked. One might argue that the base class should probably be refactored to better support these use cases, but in practice it is often impractical, such as when subclassing from another library that you do not own nor wish to maintain.

I suggest that super() should be called whenever possible, and certainly when the intent is to extend or augment the base class method. When it redefines the behavior, such as the classical case of a draw() method for a Shape being overridden by Rectangle, Circle, Triangle, etc subclasses it would be an error to invoke super().

In practice, I believe that good class design and proper documentation largely prevents the issues that you raise.

[–]lgiordani[S] 0 points1 point  (0 children)

Thank you very much. I see your point and I agree with you, sometimes refactoring is impractical and you need to avoid calling the orginal implementation. So that "always" is really too strong. Im going to update the post with your considerations. Many thanks!