目录
1)如果子类中没有定义__init__()构造函数,创建子类的对象将调用父类的__init__()构造函数,所以创建对象时必须根据父类的构造函数传入参数值;
2)如果子类中没有定义__init__()构造函数,子类继承了多个父类,排在前面的父类的构造函数会被调用;
3)子类中定义构造函数,为了初始化父类中定义的实例变量,可以直接调用实例变量进行赋值:
4)子类中定义构造函数,为了初始化父类中定义的实例变量,也可以通过调用父类的构造函数初始化;
1. 子类继承父类:
”继承房产“,”继承遗产“,”继承“都表示一个意思——”你的东西都是我的“;
子类继承父类就是子类可以使用父类中的变量和方法;
语法格式:
class 子类(父类1, 父类2, ...)
子类定义部分
从子类的角度来看,子类扩展(extend)了父类;从父类的角度来看,父类派生(derive)了子类;
class Dog:
Chinese_name = "狗"
English_name = "Dog"
def desiribe(self):
print("我们是犬科哺乳动物")
class Husky(Dog):
def infomation(self):
print("我们是一群破坏分子")
my_husky = Husky()
print(my_husky.Chinese_name) # 狗
my_husky.desiribe() # 我们是犬科哺乳动物
my_husky.infomation() # 我们是一群破坏分子
2. 多继承
python虽然语法上支持多继承,但通常推荐尽量不要使用多继承,而是使用单继承;
当一个子类有多个父类时,该子类会继承得到所有父类的方法。如果多个父类包含了同名的函数,此时对象调用该方法时会调用排在前面的父类中对应的方法;
class Dog:
Chinese_name = "狗"
English_name = "Dog"
def describe(self):
print("我们是犬科哺乳动物")
class Pet:
def describe(self):
print("我们是人类最好的朋友")
class Husky(Dog, Pet): # 定义两个子类,父类相同,但父类顺序不一样,两个父类拥有同名的方法
pass
class Bulldog(Pet, Dog):
pass
my_husky = Husky()
my_husky.describe() # 我们是犬科哺乳动物
my_bulldog = Bulldog()
my_bulldog.describe() #我们是人类最好的朋友
3. 重写父类的方法
子类包含与父类同名的方法称为方法重写;调用该方法时将调用子类的方法,父类的方法被覆盖;
class Dog:
Chinese_name = "狗"
English_name = "Dog"
def describe(self):
print("我们是犬科哺乳动物")
class Husky(Dog):
def describe(self):
print("我们是一群破坏分子")
my_husky = Husky()
my_husky.describe() # 我们是一群破坏分子
4. 调用父类中被重写的方法
通过父类名调用;
但是类名调用方法时不会为方法的第一个参数self自动指定参数值,所以需要手动指定参数值;
class Dog:
Chinese_name = "狗"
English_name = "Dog"
def describe(self):
print("我们是犬科哺乳动物")
class Husky(Dog):
def describe(self):
print("我们是一群破坏分子")
my_husky = Husky()
Dog.describe(my_husky) # 我们是犬科哺乳动物
5. 使用super函数调用父类的构造方法
Python的子类也会继承父类的构造方法,如果子类没有定义构造函数,则创建子类对象时会调用父类构造函数;子类定义了构造函数就会覆盖父类构造函数,创建子类对象就会使用子类定义的构造函数;
1)如果子类中没有定义__init__()构造函数,创建子类的对象将调用父类的__init__()构造函数,所以创建对象时必须根据父类的构造函数传入参数值;
class Dog:
def __init__(self, name):
self.name = name
def getName(self):
return self.name
class Husky(Dog):
def describe(self):
print("我们是一群破坏分子")
my_husky = Husky("林林")
# 因为子类没有定义构造函数,所以创建子类对象要调用父类的构造函数
print(my_husky.getName())
# 林林
2)如果子类中没有定义__init__()构造函数,子类继承了多个父类,排在前面的父类的构造函数会被调用;
除非排在前面的父类没有定义构造函数,否则不会调用后面的构造函数;
class Dog:
def __init__(self, name):
self.name = name
def getName(self):
return self.name
class Pet:
def __init__(self, old, sex):
self.old = old
self.sex = sex
def getOld(self):
return self.old
class Husky(Dog, Pet):
pass
my_husky = Husky(5, "boy")
# 子类Husky继承了父类Dog和Pet,所以会调用Dog的构造函数,不能调用Pet的构造函数
# 程序报错,TypeError: __init__() takes 2 positional arguments but 3 were given
3)子类中定义构造函数,为了初始化父类中定义的实例变量,可以直接调用实例变量进行赋值:
class Dog:
def __init__(self, name):
self.name = name
def getName(self):
return self.name
class Pet:
def __init__(self, old, sex):
self.old = old
self.sex = sex
def getOld(self):
return self.old
class Husky(Dog, Pet):
def __init__(self, name, old, sex):
self.name = name
self.old = old
self.sex = sex
my_husky = Husky("林林", 5, "boy")
print(my_husky.getOld()) # 5
4)子类中定义构造函数,为了初始化父类中定义的实例变量,也可以通过调用父类的构造函数初始化;
调用父类的构造函数有两种方法:
a. 使用父类名调用父类的构造函数(需要手动指定调用者);
b. 使用super()函数调用父类的构造函数;
class Dog:
def __init__(self, name):
self.name = name
def getName(self):
return self.name
class Pet:
def __init__(self, old, sex):
self.old = old
self.sex = sex
def getOld(self):
return self.old
class Husky(Dog, Pet):
def __init__(self, name, old, sex):
# 使用super()函数调用父类的构造函数,自动指定第一个参数self
super().__init__(name)
# 使用父类名调用父类的构造函数,需要手动指定第一个参数self
# 此时不能使用super()函数,因为super函数调用父类的构造函数还是先调用第一个父类的构造函数,但是第一个父类的构造函数只有两个参数,此时三个参数程序将报错;
Pet.__init__(self, old, sex)
my_husky = Husky("林林", 5, "boy")
print(my_husky.getOld()) # 5
6. super()函数
作用:python官方解释:
Typical use to call a cooperative superclass method;(用于调用相同的父类方法)
super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。
经典案例:
class A():
def __init__(self):
print('enter A')
print('leave A')
class B(A):
def __init__(self):
print('enter B')
super().__init__()
print('leave B')
class C(A):
def __init__(self):
print('enter C')
super().__init__()
print('leave C')
class D(B, C):
def __init__(self):
print('enter D')
super().__init__()
print('leave D')
d = D()
# enter D
# enter B
# enter C
# enter A
# leave A
# leave C
# leave B
# leave D