Home > Back-end >  OOP - Understanding Inheritance
OOP - Understanding Inheritance

Time:11-15

I'm beginning my journey into OOP by trying to learn inheritance. I saw this code in an online quiz about the topic and I was hoping someone could explain it to me since it makes little sense to me.

class A(object) :

    def __init__(self, x) :
        self._x = 2 * x
    def m1(self, x) :
        return self.m2(x)   2
    def m2(self, x) :
        return x - 1
    
class B(A) :

    def m2(self, y) :
        self._y = y
        return self._x   self._y

For the following, if I was to say a = A(1), what would be the expected return? The initialization multiplies the 1 with 2, so now the instance of x has value 2. What happens with the method m1? it receives this instance of X but in the return it refers to m2? so is that x=2 passed into m2 first and then the return of 1 is passed to m1? which adds 2 to it?

As for Class B, I see it changes the inherited m2 method from Class A, but the x value that is added to the y, is that an inherited x value from Class A?

Sorry about the endless questions but I'm just beginning and it seems hard to wrap my head around.

CodePudding user response:

The easiest way to figure out what the code does is to run it.

>>> a = A(1)
>>> a.m1(10)
11

An important thing to note here (which from your question it sounded like you might be confused on) is that the value of x you pass to A.__init__ does not get used by A.m1! So A.m1(x) just returns x 1 no matter how you initialized the A instance.

>>> a = A(1000)
>>> a.m1(1)
2
>>> a.m1(10)
11
>>> a.m1(100)
101

Okay, what if we make a B the same way?

>>> b = B(1)
>>> b.m1(10)
14

Now it's different, because B.m2 is different from A.m2. We can just run those on their own to see:

>>> a.m2(10)
9
>>> b.m2(10)
12

a.m2(10) is 9 because a.m2(x) is always just x - 1 regardless of what a._x is.

But b.m2(10) returns b._x 10, which in this case is 12 -- and so b.m1(10) returns that plus 2. The results will be different if we change what b._x is by initializing our B with a different value:

>>> b = B(2)
>>> b.m2(10)
14
>>> b.m1(10)
16

CodePudding user response:

You can always track what happens:

 ...
class B(A) :

    def m2(self, y) :
        self._y = y
        return self._x   self._y

class B then looks like Bx as m2 is overridden:


class Bx:

    def __init__(self, x) :
        self._x = 2 * x
    def m1(self, x) :
        return self.m2(x)   2
    def m2(self, y) :
        self._y = y
        return self._x   self._y

So this is how class B looks like-ish when it has inherited A

CodePudding user response:

I'll try answering your questions in order:

  1. If you were to say a = A(1), __init__ would set variable self._x to 2. This does not change, as you do not ever edit the self._x variable after this.

    • The functions m1 and m2 could return anything based on x that you pass in. Did you mean self._x? And yes, m2 would execute when you call m1, m1 for any number x would just return x 1.
  2. a = A(1) is just instantiating class A, the methods would work with just A(x).m1(y), whereas if you include a = A(1) you would execute a.m1(y).

  3. Instantiating class B with any number (B(x)) runs the __init__() function of A (super().init(args)) with the x passed (Try running it yourself with something like b = B(2); print(b._x)!). Thus, self._x is 2 * x that you passed for B!

  4. You have overwritten method m2() in class B, so m2() from A is not used in B.

If you have any other questions comment and I'll attempt to answer them!

  • Related