面向对象三大特征:封装 继承 多态
面向对象的两大核心概念:类和对象
一、封装
打包,包装, 包裹……
面向对象编程的第一步: 讲究将方法和属性封装到一个类中
二、继承
类与类之间存在了继承关系, 子类就可以继承父类的公有属性和公有方法
子类: 派生类,拓展类,subclass
父类: 超类,基类,superclass
属性的覆盖: 子类中覆盖父类中的类属性
派生属性: 子类中新增的, 父类中没有的属性
1、继承性
(1)子类可以继承父类的属性和方法
(2)子类可以新增自己的属性和方法
(3)子类可以重写父类已有的方法
如果需要调用父类的功能, 使用super().方法名()
2、意义
(1)提高代码的重用性
(2)拓展类的功能
1 # 惯性写法
2 父类: __init__(self, 参数1, 参数2,..):
3 self.属性1 = 参数1
4 self.属性2 = 参数2
5 ....
6 子类: __init__(self, 参数1, 参数2,....)
7 super().__init__(参数1, 参数2,...)
8 self.新增属性 = 参数
9
10 # 子类继承父类, 如果子类中没有init方法, 创建子类对象时, 会自动调用父类的init方法;
11 # 子类继承父类, 如果子类中有init方法, 创建对象时, 就不会调用父类的init方法了,
12 # 如果需要使用父类的init方法, 则程序员需要手动调用super().__init__(参数1, 参数2,...)
3、多继承
(1)多继承:子类具有多个父类的情况,子类可以继承多个父类的功能。
(2)python: (继承的传递)
多层继承: 子类 --> 父类 --> 爷爷类 --> 祖先类 ---> object类
(3)python中支持多继承:多个父类,子类可以同时拥有多个父类功能。
(4)python2:c3算法 , 深度优先;python3:c3算法, 广度优先
如果使用多继承(一个子类同时继承自多个父类), 保证父类中没有相同名字的方法;
method resolution order
可以根据 类.__mro__属性查看 当前类的父类的排序
也可以根据 类.mro() 查看当前类的父类的排序
1 class A:
2 def func1(self):
3 print("A")
4
5 class B:
6 def func1(self):
7 print("B")
8
9 class C:
10 def func1(self):
11 print("C")
12
13 class D(A, B, C):
14 pass
15
16 d = D()
17 d.func1() # A
18 print(D.__mro__) # (<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class 'object'>)
19 print(D.mro()) # [<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class 'object'>]
三、多态
1、以继承和重写为前提,形参为父类对象,执行时,由具体的对象执行相应的方法
2、非继承关系,形参为对象,执行时,由具体的对象执行相应的方法
(python鸭子类型:如果一只鸟, 长得像鸭子, 叫起来像鸭子, 走路也像鸭子, 那么我们就可以把他当做鸭子)
1 class Father:
2 def say(self):
3 print("父亲喊儿子吃饭")
4
5
6 class Son(Father): # 子类继承自父类
7 def say(self): # 子类中重写父类的方法
8 print("儿子主动回家吃饭")
9
10
11 def func(obj): # obj 是一个对象
12 if isinstance(obj, Father): # 判断obj是否是Father类的对象
13 obj.say()
14 else:
15 print("不是父亲和儿子")
16
17
18 f = Father()
19 s = Son()
20
21 func(f) # 父亲喊儿子吃饭
22 func(s) # 儿子主动回家吃饭
23
24
25 class Duck:
26 def say(self):
27 print("gaga")
28
29
30 def func2(obj): # obj 是一个对象
31 obj.say()
32
33
34 d = Duck()
35 func2(d) # 调用函数, 传参为鸭子类对象 gaga
36 func2(f) # 调用函数, 传参为父亲类对象 父亲喊儿子吃饭
37 func2(s) # 调用函数, 传参为儿子类对象 儿子主动回家吃饭