59 类的继承, 多继承, 属性查找, 类的类型与抽象

172次阅读
没有评论

共计 2972 个字符,预计需要花费 8 分钟才能阅读完成。

引入

1. 什么是继承

  • 继承是一种新建类的方式, 新建的类称为子类, 被继承的类称为父类
  • 继承的特性 : 子类会遗传父类的属性
  • 继承是类与类之间的关系

2. 为什么使用继承 (作用)

  • 使用继承可以减少代码的冗余
  • 示例:
🍔不使用继承时编写多个类
class Animal:
    def run(self):
        print(" 奔跑 ")

    def eat(self):
        print(" 吃东西 ")

class Duck:
    def run(self):
        print(" 奔跑 ")

    def eat(self):
        print(" 吃东西 ")

    def speak(self):
        print(" 嘎嘎嘎 ")

class Pig:
    def run(self):
        print(" 奔跑 ")

    def eat(self):
        print(" 吃东西 ")

    def speak(self):
        print(" 咕咕咕 ")

class Person:
    def run(self):
        print(" 奔跑 ")

    def eat(self):
        print(" 吃东西 ")

    def speak(self):
        print(" 呵呵呵 ")

🍔使用继承编写多个类
class Animal:
    def run(self):
        print(" 奔跑 ")

    def eat(self):
        print(" 吃东西 ")

class Duck(Animal):
    def speak(self):
        print(" 嘎嘎嘎 ")

class Pig(Animal):
    def speak(self):
        print(" 咕咕咕 ")

class Person(Animal):
    def speak(self):
        print(" 呵呵呵 ")

🔰# 可以明显感觉到代码量减少        

一. 类 (对象) 的继承

  • Python 中一切皆对象, 所以类也是对象
  • Python 中支持一个类同时 继承多个父类 (多继承)
class Animal:
    def run(self):
        print(" 跑起来 ")

class Work:
    def doing(self):
        print(" 敲代码 ")

class Person(Animal,Work):  # 可以继承很多个类, 用 "," 隔开
    def eat(self):
        print(" 吃东西 ")
  • __bases__ : 查看对象继承的类
print(Person.__bases__)  # (<class '__main__.Animal'>, <class '__main__.Work'>) 两个

二. 属性查找顺序

1. 多继承属性查找顺序

  • 多继承存在 属性重复问题, 多个父类中存在着相同的属性, 那么对象该选择哪个属性使用呢?

  • 按照右边顺序查找 : 对象自己 -----> 类 -----> 父类 (多个父类, 从左到右的先后顺序来找)

class Shawn:
    def Am(self):
        print("i am from Shawn")

class Pai:
    def Am(self):
        print("i am from Pai")

class Da:
    def Am(self):
        print("i am from Da")

class Xing(Pai,Shawn,Da):  # 继承了三个父类, 查找顺序: 从左到右
    pass

start = Xing()

start.Am()  # i am from Pai (找到的是最左边的)

2. 属性嵌套查找顺序 (多层继承)

  • 对象的属性 (attribute) : 我们一般是指对象的 属性和方法
  • 多层继承关系的属性查找顺序, 永远是从最下层开始找, 调用自己self.[属性]
  • 以下示例的数查找顺序 : 对象自己 -----> 对象的类 -----> 父类 -----> 父类.....

ps : Ctrl + 鼠标右键 快速跳转到属性 / 方法位置, 有时并不准确

class Bar1(object):
    def Foo1(self):
        print("i am Bar1_Foo1")

    def Foo2(self):
        print("i am Bar1_Foo2")
        self.Foo1()  ###

class Bar2(Bar1):
    def Foo1(self):
        print("i am Bar2_Foo1")

obj = Bar2()
obj.Foo2()
''' 输出
i am Bar1_Foo2   (对象自己没有到父类去找)
i am Bar2_Foo1   (执行到 "self.Foo1()" 后又返回来从最开始找)
'''

三. 新式类与经典类

1. 新式类

  • 继承了 object 的类以及该类的子类, 都是新式类 (Python3 中统一都是新式类)
  • Python3 中如果一个类没有继承任何类, 则 默认会继承 object 类, 也就是Python3 中所有的类 都是 新式类
🍔在 "Python3" 中
class Default:  # 默认继承 "object"
    pass

print(Default.__bases__)  # (<class 'object'>,)

2. 经典类

  • 没有继承 object 的类以及该类的子类, 都是经典类 (只有 Python2 中才区分新式类和经典类)
  • Python2 中如果一个类没有继承任何类, 它 不会继承object 类, 所以Python2 中才有经典类
🍔在 "Python2" 中
class Default(object):  # 新式类
    pass

class Animal:  # 经典类
    pass

🍔"Python2" 中 "print" 语法
print Default.__bases__  # (<class 'object'>,)
print Animal.__bases__   # ()

ps : 新式类与经典类的属性查找顺序是不一样的

五. 继承与抽象

  • 继承描述的是 子类与父类 之间的关系,是一种什么是什么的关系

  • 要找出这种关系,必须先抽象再继承,抽象即抽取类似或者说比较像的部分

1. 抽象

  • 将佩奇和乔治两对象比较像的部分抽取成类
  • 将人,鸭,猪这三个类比较像的部分抽取成父类
  • 抽象最主要的作用是划分类别(可以隔离关注点,降低复杂度)

59 类的继承, 多继承, 属性查找, 类的类型与抽象

2. 继承

  • 基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象的结构

59 类的继承, 多继承, 属性查找, 类的类型与抽象

  • 继承的应用
class People(object):
    school = " 蟹堡王餐厅 "

    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

class Staff(People):
    def sell(self):
        print(f"{self.name}正在卖蟹堡 ")

class Boss(People):
    def payoff(self,obj,money):
        print(f"{self.name}给 {obj.name} 发了 {money} 元工资 ")
        obj.money = money

S1 = Staff(" 海绵宝宝 ",20,"male")
B1 = Boss(" 蟹老板 ",18,"male")

S1.sell()         # 海绵宝宝正在卖蟹堡
B1.payoff(S1,300) # 蟹老板给海绵宝宝发了 300 元工资
print(S1.money)   # 300

六.Python 为类内置的特殊属性 (了解)

[类名].__name__   # 类的名字(字符串)
[类名].__doc__    # 类的文档字符串
[类名].__base__   # 类的第一个父类(在讲继承时会讲)
[类名].__bases__  # 类所有父类构成的元组(在讲继承时会讲)
[类名].__dict__   # 类的字典属性
[类名].__module__ # 类定义所在的模块
[类名].__class__  # 实例对应的类(仅新式类中)

七. 类的派生

类的派生

八. 菱形继承问题

面说到 Python 支持多继承, 但新式类与经典类的属性查找顺序是不一样的

菱形继承问题

正文完
 
shawn
版权声明:本站原创文章,由 shawn 2023-06-16发表,共计2972字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)