python子类继承父类构造函数__init__的几种情况
1. 子类不重写父类的__init__方法,那么子类继承父类的__init__
实例:
class Father(object):
def __init__(self, name):
self.name = name
print("name: %s" % (self.name))
def getName(self):
return 'Father ' + self.name
class Son(Father):
def getName(self):
return 'Son ' + self.name
if __name__ == '__main__':
son = Son('runoob')
print(son.getName())
输出结果:
name: runoob
Son runoob
2. 子类重写父类的__init__方法,就不会调用父类的__init__
实例:
class Father(object):
def __init__(self, name):
self.name = name
print("name: %s" % (self.name))
def getName(self):
return 'Father ' + self.name
class Son(Father):
def __init__(self, name):
print("hi")
self.name = name
def getName(self):
return 'Son ' + self.name
if __name__ == '__main__':
son = Son('runoob')
print(son.getName())
输出结果:
hi
Son runoob
3. 如果子类重写了__init__,要继承父类的构造方法,有两种方法
一种是使用super关键字:
super(子类,self).__init__(参数1,参数2,....) 或者 super().__init__(参数1,参数2,....)
另一种是使用:
父类.__init__(self,参数1,参数2,...)
实例:
class Father(object):
def __init__(self, name):
self.name = name
print("name: %s" % (self.name))
def getName(self):
return 'Father ' + self.name
class Son(Father):
def __init__(self, name):
super(Son, self).__init__(name) # 两种形式都可以
# Father.__init__(self, name)
print("hi")
self.name = name
def getName(self):
return 'Son ' + self.name
if __name__ == '__main__':
son = Son('runoob')
print(son.getName())
输出结果:
name: runoob
hi
Son runoob
使用super和使用父类这两种方法是有区别的:
1.使用父类.__init__(self,参数1,参数2,...)的方式,这种写法比较清晰易懂,但是与父类类名绑定,而且在菱形继承场景下顶层父类初始化函数会被调用多次;
2.使用super类的方式调用父类初始化方法,这种写法不与父类类名绑定,且可以保证菱形继承场景下,创建一个子类对象仅调用顶层父类初始化函数一次。
实例:使用父类的方式
class Ancestor:
def __init__(self):
print("ancestor initialize invoked")
class Base(Ancestor):
def __init__(self, base_attr):
Ancestor.__init__(self)
self.base_attr = base_attr
class BaseTwo(Ancestor):
def __init__(self, base_two_attr):
Ancestor.__init__(self)
self.base_two_attr = base_two_attr
class Derived(Base, BaseTwo):
def __init__(self, base_attr, base_two_attr, derived_attr):
Base.__init__(self, base_attr)
BaseTwo.__init__(self, base_two_attr)
self.derived_attr = derived_attr
if __name__ == '__main__':
derived_obj = Derived(1, 2, 3) # "ancestor initialize invoked" will print twice.
print(derived_obj.base_attr) # 1
print(derived_obj.base_two_attr) # 2
输出结果:
ancestor initialize invoked
ancestor initialize invoked
1
2
实例:使用super的方式
class Ancestor:
def __init__(self, **kwargs):
print("ancestor initialize invoked")
class Base(Ancestor):
def __init__(self, base_attr, **kwargs):
super().__init__(**kwargs)
self.base_attr = base_attr
class BaseTwo(Ancestor):
def __init__(self, base_two_attr, **kwargs):
super().__init__(**kwargs)
self.base_two_attr = base_two_attr
class Derived(Base, BaseTwo):
def __init__(self, base_attr, base_two_attr, derived_attr, **kwargs):
super().__init__(base_attr=base_attr, base_two_attr=base_two_attr, **kwargs)
self.derived_attr = derived_attr
if __name__ == '__main__':
derived_obj = Derived(1, 2, 3)
print(derived_obj.base_attr) # 1
print(derived_obj.base_two_attr) # 2
输出结果:
ancestor initialize invoked
1
2