面向对象三大特征:封装 继承 多态
面向对象的两大核心概念:类和对象
一、封装
打包,包装, 包裹……
面向对象编程的第一步: 讲究将方法和属性封装到一个类中
二、继承
类与类之间存在了继承关系, 子类就可以继承父类的公有属性和公有方法
子类: 派生类,拓展类,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) # 调用函数, 传参为儿子类对象 儿子主动回家吃饭