0

In a python program, I implemented some class A, and a subclass B which extends some of A's methods and implements new ones. So it's something that looks like this.

class A:
    def method(self):
        print("This is A's method.")

class B(A):
    def method(self):
        super().method()
        print("This is B's method.")

    def another_method(self):
        pass

Later, I wanted to use an object which would have access to all of B's methods, except for a small change in method: this object would have to first call A.method, and then do other things, different from what I added in B.method. I thought it was natural to introduce a class C which would inherit from B but modify method, so I defined C like this.

class C(B):
    def method(self):
        super(B, self).method()
        print("This is C's method.")

Everything seems to work as I expect. However, I stumbled across this question and this one, which both address similar problems as what I described here. In both posts, someone quickly added a comment to say that calling a grandparent method in a child when the parent has overridden this method is a sign that there is something wrong with the inheritance design.

How should I have coded this? What would be a better design? Of course this is a toy example and I guess the answer might depend on the actual classes I defined. To give a more complete picture, let's say the method method from the example represents a single method in my actual program, but the method another_method represents many different methods.

Vincent
  • 200
  • 2
  • 8
  • 2
    A child should only know about its direct parent. It shouldn't know about nor interact with grandparents. Your inheritance structure is simply wrong. `C` can choose to completely replace `method`, or use its parent's `method` plus something of its own. `C.method` shouldn't be doing something `B` is not. You need to structure your hierarchy so `C.method` is an extension of `B.method` in what it does. – deceze Jun 01 '21 at 19:38
  • 1
    Maybe `B` should be split into multiple classes. One overrides `A.method`, the other doesn't. Then `C` could inherit from the one that doesn't override. – Barmar Jun 01 '21 at 19:40
  • 2
    The problem is your application model in general. If you explain what all these classes actually represent, we might be able to explain how to structure it better. – Barmar Jun 01 '21 at 19:41
  • Thanks for your comments! @Barmar these classes represent solutions of differential equations that I integrate numerically. `B` and `C` represent the solutions to very similar systems, but there is a part of the initialization (done in `method`) that is done differently. – Vincent Jun 01 '21 at 20:29
  • Maybe you should extract the part that's common between A and C into a separate method that can be called from both A.method and C.method. – Barmar Jun 01 '21 at 22:57
  • @Barmar that's what I thought I would do, it seems to make more sense. Thanks again! – Vincent Jun 01 '21 at 23:23

0 Answers0