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:
If you were to say
a = A(1),__init__would set variable self._x to2. This does not change, as you do not ever edit theself._xvariable after this.- The functions
m1andm2could return anything based onxthat you pass in. Did you meanself._x? And yes,m2would execute when you callm1,m1for any numberxwould just returnx 1.
- The functions
a = A(1)is just instantiating classA, the methods would work with justA(x).m1(y), whereas if you includea = A(1)you would executea.m1(y).Instantiating class
Bwith any number (B(x)) runs the__init__()function ofA(super().init(args)) with thexpassed (Try running it yourself with something likeb = B(2); print(b._x)!). Thus,self._xis2 * xthat you passed for B!You have overwritten method
m2()in classB, som2()fromAis not used inB.
If you have any other questions comment and I'll attempt to answer them!
