Python类学习(六)——继承

目录

1. 子类继承父类:

2. 多继承

3. 重写父类的方法

4. 调用父类中被重写的方法

5. 使用super函数调用父类的构造方法

1)如果子类中没有定义__init__()构造函数,创建子类的对象将调用父类的__init__()构造函数,所以创建对象时必须根据父类的构造函数传入参数值;

2)如果子类中没有定义__init__()构造函数,子类继承了多个父类,排在前面的父类的构造函数会被调用;

3)子类中定义构造函数,为了初始化父类中定义的实例变量,可以直接调用实例变量进行赋值:

4)子类中定义构造函数,为了初始化父类中定义的实例变量,也可以通过调用父类的构造函数初始化;

6. super()函数


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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值