共计 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. 抽象
- 将佩奇和乔治两对象比较像的部分抽取成类
- 将人,鸭,猪这三个类比较像的部分抽取成父类
- 抽象最主要的作用是划分类别(可以隔离关注点,降低复杂度)
2. 继承
- 基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象的结构
- 继承的应用
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 支持多继承, 但新式类与经典类的属性查找顺序是不一样的
正文完