Day21 抽象接口多太鸭子类型

Posted 欣蔚

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Day21 抽象接口多太鸭子类型相关的知识,希望对你有一定的参考价值。

面向对象复习:

派生方法和派生属性:

  super只有在子父类拥有同名方法的时候

  想使用子类的对象调用父类的方法时,才使用super

  super在类内:super().方法名(args1,..)

多继承 钻石继承

  经典类 python2 不继承object

    查找名字遵循深度优先遍历算法

  新式类 python3中都是新式类 在py2中继承object

    查找名字遵循广度优先遍历算法

      每一个节点可以在深度广度上都有机会被访问到的时候,只有一次

      优先从广度上查找

    类名.mro()方法可以查看广度优先的顺序

    super()的作用:在广度优先中查看当前这个类的上一个节点

      在py2中super必须传参,super(子类名,self).方法名(args1,...)

 

# 抽象类和接口类
  java 编程原则和设计模式
  设计模式 程序设计 具有里程碑意义的设计方式 从java中演变出来的

    单例模式:

    一个类只有一个实例

# 编程原则
  # python
  # 开放封闭原则
    # 开放 对扩展是开放的
    # 封闭 对修改是封闭的
  # 依赖倒置原则
  # 接口隔离原则
# 已经写完的程序代码是不允许修改的

# 支付功能的例子
  # 支付宝支付
  # qq支付
  # apply_pay
  # 微信支付

# 创建一个规范
from abc import ABCMeta,abstractmethod
class Payment(metaclass=ABCMeta): # 抽象类 接口类  规范和约束  metaclass指定的是一个元类
    @abstractmethod
    def pay(self):pass
class Alipay:
    def pay(self,money):
        print(使用支付宝支付了%s元%money)

class QQpay:
    def pay(self,money):
        print(使用qq支付了%s元%money)

class Wechatpay:
    def pay(self,money):
        print(使用微信支付了%s元%money)

def pay(a,money):
    a.pay(money)

a = Alipay()
a.pay(100) #归一化设计:不管是哪一个类的对象,都调用同一个函数去完成相似的功能
q = QQpay()
q.pay(80)
w = Wechatpay()
w.pay(50)
# 归一化设计
# l = [1,2,2]
# l2 = {1,2,3,4}
# l3 = (1,2)
# a = ‘1234567‘
# print(len(l))
# print(l3.__len__())
# len()  和 __len__()
# 只有一个类中实现了__len__()方法,才能使用len()函数
# def len2(obj):  # 归一化设计
#     return obj.__len__()

# print(len(l))
# print(len(l2))
# print(len(l3))

抽象类和接口类做的事情:建立规范

指定一个类的metaclass是ABCMeta 那么这个类就变成了一个抽象类(接口类)这个类的主要功能就是建立一个规范

抽象类中所有被abstractmethod装饰的方法都必须被继承的子类实现

如果不实现,那么在实例化阶段会报错

无论是抽象类和接口类metaclass=ABCMeta都不可以被实例化

p = payment() #报错

接口隔离原则

什么叫接口
python里没有接口的概念
那接口是哪儿来的概念呢?
java类没有多继承 接口可以实现多继承
# 描述动物园
# 会游泳的 会走路的 会爬树的 会飞的
# 老虎
# 青蛙
# 天鹅
# 猴子

from abc import ABCMeta,abstractmethod
class FlyAnimal(metaclass = ABCMeta):
    @abstractmethod
    def fly(self):pass
    @abstractmethod
    def cal_flying_speed(self):pass
    @abstractmethod
    def cal_flying_height(self):pass
class WalkAnimal(metaclass=ABCMeta):
    @abstractmethod
    def walk(self):pass
class SwimAnimal(metaclass = ABCMeta):
    @abstractmethod
    def swim(self):pass
class Tiger(WalkAnimal,SwimAnimal):
    def walk(self):pass
    def swim(self):pass
class Monkey(WalkAnimal):
    def walk(self):pass
    def climb(self):pass
class Swan(FlyAnimal,WalkAnimal,SwimAnimal):
    def fly(self):pass
    def cal_flying_speed(self):pass
    def cal_flying_height(self):pass
    def walk(self):pass
    def swim(self):pass
class Parrot(FlyAnimal):
    def fly(self):pass
    def cal_flying_speed(self):pass
    def cal_flying_height(self):pass

# 所有会飞的动物 具有一些会飞的动物的特性
# 所有会走的动物 具有一些会走的动物的特性

#接口类的作用:

  在java中,能够满足接口隔离原则,且完成多继承的约束

  而在python中,由于python本身支持多继承,所有不需要接口的概念了

# 抽象类和接口类

在python中:

  并没有什么不同,都是用来约束子类中的方法

  只要是抽象类和接口类中被abstractmethod装饰的方法,都需要被子类实现

  需要注意的是,当多个类之间有相同的功能也有不同的功能的时候,应该采用多个接口类来进行分别的约束

在java中:

  抽象类和接口截然不同

  抽象类的本质还是一个类,是类就必须遵循单继承的规则,所以一个子类如果被抽象类约束,那么它只能被一个父类控制

  当多个类之间有相同的功能也有不同的功能的时候  java只能用接口来解决问题

 

面试题:

  抽象类是python中定义类的一种规范

  在python中没有接口的概念,但是有接口的功能,多说一些显示对其他语言的了解

# 在公司里写代码的时候如果遇到抽象类,记得按照抽象类中的规范一一去是实现对应的方法

 面试题:

多态:一定是通过继承实现的

  在java中:一个类之下发展出来的多个类的对象都可以作为参数传入一个函数

  在python天生自带多态效果,无论python2还是python3,都不需要刻意实现多态

 

# 多态
  # java c++ c# —— 强类型语言
  # 相同数据类型之间做运算
  # def func(int a):pass
  # func(‘a‘)

  # shell语言 —— 弱类型语言
  # 1+‘1‘
  # def func(a):pass
  # 1 ‘a‘ [1,2,3] ()

# 介于 强类型 与 弱类型之间 —— python 动态强类型语言

相同数据类型之间做运算

# def func(a):pass
class Payment:
    def pay(self):pass

class QQpay(Payment):
    def pay(self,money):
        print(使用qq支付了%s元%money)

class Wechatpay(Payment):
    def pay(self,money):
        print(使用微信支付了%s元%money)
    def recharge(self):pass

# def pay(Payment pay_obj,int money):   #  java 多态 在一个类之下发展出来的多个类的对象都可以作为参数传入这里
#     pay_obj.pay(money)

# 无论是python的2.*还是3.* : 天生自带多态效果
# qq_obj = QQpay()
# print(type(qq_obj))  # 一个对象的数据类型就是它所在的类
# # # qq_obj.pay(100)
# pay(qq_obj,100)
# we_obj = Wechatpay()
# # # we_obj.pay(200)
# pay(we_obj,200)
# def len(object obj):pass
# class len_class:pass
# class tuple(len_pass):pass
# class list(len_pass):pass
# class str(len_pass):pass
# tuple list str dict set

<class ‘__main__.QQpay‘>
使用qq支付了100元
使用微信支付了200元

鸭子类型

Python崇尚鸭子类型,即‘如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子’

python程序员通常根据这种行为来编写程序。例如,如果想编写现有对象的自定义版本,可以继承该对象

也可以创建一个外观和行为像,但与它无任何关系的全新对象,后者通常用于保存程序组件的松耦合度。

# class QQpay():
#     def pay(self,money):
#         print(‘使用qq支付了%s元‘%money)
#
# class Wechatpay():
#     def pay(self,money):
#         print(‘使用微信支付了%s元‘%money)
#
# def pay(pay_obj,money):
#     pay_obj.pay(money)
例2:序列类型有多种形态:字符串,列表,元组,但他们直接没有直接的继承关系
# 索引
class list:
    def index(self):pass
class str:
    def index(self):pass
class tuple:
    def index(self):pass
# [].index()
# ‘‘.index()
# ().index()

# 鸭子类型:python
  # 不是通过具体的继承关系来约束某些类中必须有哪些方法名
  # 是通过一种约定俗成的概念来保证在多个类中相似的功能叫相同的名字

 

  

以上是关于Day21 抽象接口多太鸭子类型的主要内容,如果未能解决你的问题,请参考以下文章

封装- --接口,抽象, 鸭子类型 #22

023_接口类,抽象类,多态,鸭子类型,封装

day20

day21接口类和抽象类,隔离原则,开放封闭原则,多态

关于python鸭子类型和白鹅类型

day_21(接口类,抽象类,封装)