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._x
variable after this.- The functions
m1
andm2
could return anything based onx
that you pass in. Did you meanself._x
? And yes,m2
would execute when you callm1
,m1
for any numberx
would 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
B
with any number (B(x)
) runs the__init__()
function ofA
(super().init(args)
) with thex
passed (Try running it yourself with something likeb = B(2); print(b._x)
!). Thus,self._x
is2 * x
that you passed for B!You have overwritten method
m2()
in classB
, som2()
fromA
is not used inB
.
If you have any other questions comment and I'll attempt to answer them!