01
引言
许多同学在开始学习Python中的面向对象编程时,对于子类的构造函数的初始化操作,经常会感到些许困惑,这里我来试图让它不那么令人困扰。
02
准备工作
在面向对象编程中,为了实现多态,他们经常需要使用继承的思想。对于父类和子类,我们必须非常清楚__init___()函数的作用。
in the SAME number of args parent & child takes
# Animal(name, age) # parent class
# child class Dog(name, age)
接着是子类参数量多于父类的情况,如下:
in MORE args than parent child takes
# Employee(name, age) # parent class
# child class Executive(name, age, rank)
最后是子类参数量少于父类的情形,如下:
in FEWER args than parent child takes
# Rectangle(length, width) # parent class
# child class Square(length)
03
情形一:子类父类参数量一致
# parent class
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
接着是子类Dog的定义:
# child class
class Dog(Animal):
# Dog's __init__ should follow Dog(name, age)
def __init__(self, name, age):
# super().__init__ here refers to Animal.__init__
super().__init__(name, age)
由于我们的子类Dog继承自父类Animal, 所以当我们运行子类Dog中的__init__函数时:
super()指的是Dog的父类Amimal
super().__init__()指的是父类Animal中的__init__函数
当super().__init__()运行时,实质上是Animal中__init__函数在运行,即执行语句self.name=name 以及 self.age=age
由于父类Animal和子类Dog的初始化参数都是(name,age) , 所以我们不需要修改子类Dog的__init__函数,我们只需要在子类Dog中简单地使用父类的__init__方法即可。
04
情形二:子类参数量比父类参数量多
我们对上述父类Employee(name, age)和 子类Executive(name, age, rank), 进行简单定义实现。
# parent class
class Employee:
def __init__(self, name, age):
self.name = name
self.age = age
接着是子类Executive的定义:
# child class
class Executive(Employee):
# Executive.__init__ follows Executive(name, age, rank)
def __init__(self, name, age, rank):
# super().__init__ refers to Employee.__init__
# super().__init__ should follow Employee(name, age)
super().__init__(name, age)
# super().__init__() does not set rank, so we must do it manually
self.rank = rank
同上,当我们在子类Executive调用super().__init__()时,我们实质上运行的是父类Employee中的 self.name = name 和self.age = age 。同时由于父类Employee中并没有初始化参数rank , 因此我们需要在子类Executive中手动指定改参数的初始化。
05
情形三:子类参数量比父类参数量少
我们对上述父类 Rectangle(length, width) 和子类Square(length) , 进行简单定义实现。
# parent class
class Rectangle:
def __init__(self, length, width):
self.length = length
self.width = width
接着是子类Square的定义:
# chid class
class Square(Rectangle):
# Square.__init__ should follow Square(length)
def __init__(self, length):
# super().__init__ should follow Rectangle()
super().__init__(length, length)
我们知道,在子类正方形中默认length=width,所以我们对该类的__init__函数只需要传入一个参数length即可。同样的当我们在子类Square中调用super().__init__()函数时,我们调用的是父类Rectangle中的__init__函数。
06
总结
嗯嗯,您学废了嘛?
点击上方小卡片关注我
寄语:
我们所听到的一切,都是一个观点,不是事实。
我们所看到的一切,都是一个视角,不是真相。