一回顾
面向对象
1. 类: 具有相同属性和方法 的一类事物
类名可以实例化一个对象
类名可以调用类属性,(静态属性 和 (方法) 动态属性)
2. 对象: 也就是实例
对象名: 调用对象属性
调用方法
3. 什么叫抽象?
从小到大的过程
4. 组合 ----- 什么有什么的关系(将一个类的对象当做另一个类的属性)
5. 继承 ----- 什么是什么的关系
从大范围到小范围的过程
继承的作用: 减少代码的重用性
子类有的方法, 就用子类的不会调用父类的方法
如果要在子类中调用父类的方法: super(). 类名()
6. 派生: 父类没有的子类有了
派生类: 在父类的基础上, 又产生了子类, 这个子类就叫做派生类
派生属性: 父类里没有的属性但子类中有了的属性就叫做派生方法
派生方法: 父类里没有的方法但子类中有了的方法就叫做派生方法
7. 方法的重写
父类里有子类里也有的方法叫做方法的重写
二接口类与抽象类
1. 接口类:(在抽象类的基础上)
在 python 中, 默认是没有接口类的
接口类不能被实例化(如果实例化会报错)
接口类中的方法不能被实现
1. 正常调用
- class Applepay:
- def pay(self,money):
print(apple pay 支付了 %s %money)
- class Alipay:
- def pay(self,money):
print(支付宝 支付了 %s %money)
- def payment(pay_obj,money): #实例化的另一种调用, 这个方法让实例化的时候按照 payment 调用: 就像下面的 payment(apple1,200)
- pay_obj.pay(money)
- apple1 = Applepay()
- # apple1.pay(200)
- payment(apple1,200)
- # 2. 有时候写的时候会把方法写错, 自己定义一个主动报错
- # 接口初成: 手动报异常: NotImplementedError 来解决开发中遇到的问题
- class Payment:
- def pay(self):
- raise NotImplementedError #主动让程序报错
- class Wechatpay(Payment): #微信支付
- def pay(self,money):
print(微信支付了 %s 元, money)
- class QQchatpay(Payment): #QQ 支付
- def fuqian(self,money):
print(QQ 支付了 %s 元, money)
- p = Wechatpay()
- p.pay(200) #不报错
- q = QQchatpay() #不报错
- q.pay() #报错
- # 3. 借用 abc 模块来实现接口
- # 接口类(就是为了提供标准, 约束后面的子类)
- from abc import ABCMeta,abstractmethod
- class Payment(metaclass=ABCMeta):
- @abstractmethod
- def pay(self,money):
- pass
- class Wechatpay(Payment):
- def fuqian(self,money):
实现了 pay 的功能, 但是方法名字不一样
print(微信支付了 %s 元 %money)
- class Alipay:
- def pay(self,money):
print(支付宝 支付了 %s %money)
- # p = Wechatpay() #报错了(因为上面定义了一个接口类, 接口类里面
- # 定义了一个 pay 方法, 而在下面的 Wechatpay 方法里没有 pay 方法, 不能
- # 调用, 在接口类里面约束一下, 接口类里的 pay 方法里面不能写其他, 直接 pass)
- a = Alipay()
- a.pay(200)
- p = Payment() #接口类不能被实例化
为何要用接口
接口提取了一群类共同的函数, 可以把接口当做一个函数的集合
然后让子类去实现接口中的函数
这么做的意义在于归一化, 什么叫归一化, 就是只要是基于同一个接口实现的类, 那么所有的这些类产生的对象在使用时, 从用法上来说都一样
归一化, 让使用者无需关心对象的类是什么, 只需要的知道这些对象都具备某些功能就可以了, 这极大地降低了使用者的使用难度
比如: 我们定义一个动物接口, 接口里定义了有跑吃呼吸等接口函数, 这样老鼠的类去实现了该接口, 松鼠的类也去实现了该接口, 由二者分别产生一只老鼠和一只松鼠送到你面前, 即便是你分别不到底哪只是什么鼠你肯定知道他俩都会跑, 都会吃, 都能呼吸
再比如: 我们有一个汽车接口, 里面定义了汽车所有的功能, 然后由本田汽车的类, 奥迪汽车的类, 大众汽车的类, 他们都实现了汽车接口, 这样就好办了, 大家只需要学会了怎么开汽车, 那么无论是本田, 还是奥迪, 还是大众我们都会开了, 开的时候根本无需关心我开的是哪一类车, 操作手法 (函数调用) 都一样
接口也就是做约束, 让下面的类的方法都按照接口类中给出的方法去定义如果接口类里面有的方法类里面没有, 那么那个类就不能被实例化(字面理解)
继承的第二种含义非常重要它又叫接口继承
接口继承实质上是要求做出一个良好的抽象, 这个抽象规定了一个兼容接口, 使得外部调用者无需关心具体细节, 可一视同仁的处理实现了特定接口的所有对象这在程序设计上, 叫做归一化
2. 抽象类:
在 python 中, 默认是有的
父类的方法, 子类必须实现
抽象类 (父类) 的方法可以被实现
- # 抽象类
- # 什么叫做抽象? 从小范围到大范围
- from abc import ABCMeta,abstractmethod
- class Animal(metaclass=ABCMeta):
- @abstractmethod
- def eat(self):
print(打开粮食的袋子)
print(放一个吃饭的碗)
print(吧粮食倒在碗里)
- @abstractmethod
- def sleep(self):
- pass
- class Dog(Animal):
- #实现吃喝睡的方法
- def eat(self):
- super().eat()
- # super(Dog, self).eat()
- print(dog is eating)
- def sleep(self):
- print(dog is sleeping)
- # d = Dog()
- # d.eat()
- a = Animal() #抽象类不能被实例化
3. 抽象类和接口类的区别: 接口类不能实现方法, 抽象类可以实现方法里面的内容
4. 抽象类和接口类的相同点: 都是用来做约束的, 都不能被实例化
5. 抽象类和接口类的使用:
当几个子类的父类有相同的功能需要被实现的时候就用抽象类
当几个子类有相同的功能, 但是实现各不相同的时候就用接口类
6.python 中的抽象类和接口类在 Java 里面的区别
接口类支持多继承
抽象类只支持单继承
三多继承
在继承抽象类的过程中, 我们应该尽量避免多继承;
而在继承接口的时候, 我们反而鼓励你来多继承接口
接口隔离原则:
使用多个专门的接口, 而不是用单一的总接口即客户端不应该依赖那些不需要的接口
- class A:
- def test(self):
- print(from A)
- class B(A):
- def test(self):
- print(from B)
- class C(A):
- def test(self):
- print(from C)
- class D(A):
- def test(self):
- print(from D)
- class E(B):pass
- # def test(self):
- # print(from E)
- class F(E,D,C):pass
- # def test(self):
- # print(from F)
- # b= B()
- # b.test()
- # d = D()
- # d.test() #一级一级往上找, 自己没有, 就继承爹的, 爹没有就找爷爷的
- # 再找不到就报错了
- f = F()
- f.test()
- print(F.mro()) #查看找父类的顺序
四钻石继承
新式类: 广度优先: 横着找(如钻石继承图, 谁先在前面就找谁)
经典类: 深度优先: 从上到下找
五多态
多态指的是一类事物有多种形态(比如: 老师. 下课铃响了(), 学生. 下课铃响了(), 老师执行的是下班操作, 学生执行的是放学操作, 虽然二者消息一样, 但是执行的效果不同)
例如: 动物有多种形态: 人, 狗, 猪
- from abc import ABCMeta,abstractmethod
- class Animal(metaclass=ABCMeta):
- @abstractmethod
- def eat(self):pass
- class Cat(Animal): #动物的形态之一: 猫
- def eat(self):
- print(cat eat)
- class Dog(Animal): #动物的形态之二: 狗
- def eat(self):
- print(dog eat)
- class Pig(Animal):pass #动物的形态之三: 猪
- def eat_fun(animal_obj): #定义一个函数让这个函数名去调用
- animal_obj.eat()
- c = Cat()
- eat_fun(c) #函数名(对象)
- d = Dog()
- eat_fun(d)
- c = Cat()
- c.eat()
python 自带多态:
多态: 同一类事物的多种状态
python 里处处都是多态, 只是我们一般发现不了
操作的时候不需要关心这个对象的数据类型, 你只要用就行了
静态多态性(了解就好)
鸭子类型(如果两个类里面都有相同的方法, 但是他们的类里面没有任何继承)
序列(str,list,tuple): 有顺序的数据集合, 这三个没有任何继承
来源: http://www.bubuko.com/infodetail-2500685.html