2014年11月6日 星期四

python inheritance note

Reference
http://www.artima.com/weblogs/viewpost.jsp?thread=281127
http://apt-blog.net/constructors_with_different_arguments_in_python_multiinheri_class

Python Inheritance 繼承
繼承型態如下
class DerivedClassName(BaseClassName):
<statement-1>
.
.
.
<statement-N>

舊式繼承
class Father:
def __init__(self,f_name,f_age):
self.f_name = f_name
self.f_age = f_age

def f_info(self):
print("papa name:",self.f_name,"papa age:",self.f_age)

class Child(Father):
def __init__(self,c_name,c_age,f_name,f_age):
Father.__init__(self,f_name,f_age)
self.c_name = c_name
self.c_age = c_age
self.f_info()

def fam_info(self):
print("age sum:",self.f_age+self.c_age)


python 3以後可以用super來繼承,父類繼承object才能使用super函式,即使是多重繼承也只需要呼叫一次super()
class Father(object):
def __init__(self,f_name,f_age):
self.f_name = f_name
self.f_age = f_age

def f_info(self):
print("papa name:",self.f_name,"papa age:",self.f_age)

class Child(Father):
def __init__(self,c_name,c_age,f_name,f_age):
super(Child,self).__init__(f_name,f_age)
self.c_name = c_name
self.c_age = c_age
self.f_info()

def fam_info(self):
print("age sum:",self.f_age+self.c_age)

>>> d = Child('mary',10,'john',40)
('papa name:', 'john', 'papa age:', 40)
>>> d.fam_info()
('age sum:', 50)


Multi Inheritance 多重繼承
繼承順序是由左到右

舊式
class Father:
def __init__(self,f_name,f_age):
self.f_name = f_name
self.f_age = f_age

def f_info(self):
print("papa name:",self.f_name,"papa age:",self.f_age)


class Mother:
def __init__(self,m_name,m_age):
self.m_name = m_name
self.m_age = m_age

def m_info(self):
print("mama name:",self.m_name,"mama age:",self.m_age)

class Child(Father,Mother):
def __init__(self,c_name,c_age,f_name,f_age,m_name,m_age):
Father.__init__(self,f_name,f_age)
Mother.__init__(self,m_name,m_age)
self.c_name = c_name
self.c_age = c_age
self.f_info()
self.m_info()

def fam_info(self):
print("age sum:",self.f_age+self.m_age+self.c_age)




>>> d = Child('mary',10,'john',40,'ann',35)
('papa name:', 'john', 'papa age:', 40)
('mama name:', 'ann', 'mama age:', 35)
>>> d.fam_info()
('age sum:', 85)

新式繼承super
super在單繼承跟多繼承有兩種不同的工作方式
將父類別繼承母類別,再由子類別繼承父類別來呼叫父母類別的函式

class Mother(object):
def __init__(self,m_name,m_age):
self.m_name = m_name
self.m_age = m_age

def m_info(self):
print("mama name:",self.m_name,"mama age:",self.m_age)


class Father(Mother):
def __init__(self,f_name,f_age,m_name,m_age):
super(Father,self).__init__(m_name,m_age)
self.f_name = f_name
self.f_age = f_age

def f_info(self):
print("papa name:",self.f_name,"papa age:",self.f_age)

class Child(Father,Mother):
def __init__(self,c_name,c_age,f_name,f_age,m_name,m_age):
super(Child,self).__init__(f_name,f_age,m_name,m_age)
self.c_name = c_name
self.c_age = c_age
self.f_info()
self.m_info()

def fam_info(self):
print("age sum:",self.f_age+self.m_age+self.c_age)


如果使用super有多重分支,會走上最上層的父繼承,再走另一分支
因為他在多重繼承裡使用MRO (Method Resolution Order)
MRO是深度優先的繼承列表
class A(object):
def __init__(self):
super(A,self).__init__()
print "A"

class B(A):
def __init__(self):
super(B,self).__init__()
print "B"


class C(A):
def __init__(self):
super(C,self).__init__()
print "C"


class D(object):
def __init__(self):
super(D,self).__init__()
print "D"

class E(B,C,D):
def __init__(self):
super(E,self).__init__()
print "E"
>>> d = E()
D
A
C
B
E
>>>

上例如果沒有super做多重繼承的話,必須找出繼承順序寫在子類別中
class A(object):
def __init__(self):
print "A"

class B(A):
def __init__(self):
print "B"


class C(A):
def __init__(self):
print "C"


class D(object):
def __init__(self):
print "D"

class E(B,C,A,D):
def __init__(self):
D.__init__(self)
A.__init__(self)
C.__init__(self)
B.__init__(self)
print "E"

>>> d = E()
D
A
C
B
E



沒有留言:

張貼留言