前言

”面向接口编程“写 Java 的朋友耳朵已经可以听出干茧了吧,当然这个思想在 Java 中非常重要,甚至几乎所有的编程语言都需要,毕竟程序具有良好的扩展性、维护性谁都不能拒绝。

最近无意间看到了我刚开始写 Python 时的部分代码,当时实现的需求有个很明显的特点:不同对象具有公共的行为能力,但具体每个对象的实现方式又各不相同。

说人话就是商户需要接入平台,接入的步骤相同,但具体实现不同。

作为一个”资深“ Javaer,需求还没看完我就洋洋洒洒的把各个实现类写好了:

当然最终也顺利实现需求,甚至把组里一个没写过 Java 的大哥唬的一愣一愣的,直呼牛逼。

不过事后也给我吐槽:你这设计是不错,但是感觉好复杂,跟代码时要找到真正的业务逻辑(实现类)得绕几圈。

截止目前 Python 写多了,我总算是能总结他的感受:就是不够 Pythonic。

虽说 Python 没有类似 Java 这样的 Interface 特性,但作为面向对象的高级语言也是支持继承的;

在这里我们也可以利用继承的特性来实现面向接口编程:class Car:

def run(self):

pass

class Benz(Car):

def run(self):

print("benz run")

class BMW(Car):

def run(self):

print("bwm run")

def run(car):

car.run()

if __name__ == "__main__":

benz = Benz()

bmw = BMW()

run(benz)

run(bmw)

代码非常简单,在 Python 中也没有类似于 Java 中的 extends 关键字,只需要在类声明末尾用括号包含基类即可。

这样在每个子类中就能单独实现业务逻辑,方便扩展和维护。

类型检查

由于 Python 作为一个动态类型语言,无法做到 Java 那样在编译期间校验一个类是否完全实现了某个接口的所有方法。

为此 Python 提供了解决办法,那就是 abc(Abstract Base Classes) ,当我们将基类用 abc 声明时就能近似做到:import abc

class Car(abc.ABC):

@abc.abstractmethod

def run(self):

pass

class Benz(Car):

def run(self):

print("benz run")

class BMW(Car):

pass

def run(car):

car.run()

if __name__ == "__main__":

benz = Benz()

bmw = BMW()

run(benz)

run(bmw)

一旦有类没有实现方法时,运行期间便会抛出异常:bmw = BMW()

TypeError: Can't instantiate abstract class BMW with abstract methods run

虽然无法做到在运行之前(毕竟不需要编译)进行校验,但有总比没有好。

鸭子类型

以上两种方式看似已经毕竟优雅的实现面向接口编程了,但实际上也不够 Pythonic。

在继续之前我们先聊聊接口的本质到底是什么?

在 Java 这类静态语言中面向接口编程是比较麻烦的,也就是我们常说的子类向父类转型,因此需要编写额外的代码。

带来的好处也是显而易见,只需要父类便可运行。

但我们也不必过于执着于接口,它本身只是一个协议、规范,并不特指 Java 中的 Interface,甚至有些语言压根没有这个关键字。

动态语言的特性也不需要强制校验是否实现了方法。

在 Python 中我们可以利用鸭子类型来优雅的实现面向接口编程。

在这之前先了解下鸭子类型,借用维基百科的说法:“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”

我用大白话翻译下就是:

即便两个完全不想干的类,如果他们都实现了相同的方法,那就可以把他们当做同一类型的类来使用。

举个简单例子:class Order:

def create(self):

pass

class User:

def create(self):

pass

def create(obj):

obj.create()

if __name__ == "__main__":

order = Order()

user = User()

create(order)

create(user)

这里的 order 和 user 本身完全没有关系,只是他们都有相同方法,又得益于动态语言没法校验类型的特点,所以完全可以在运行的时候认为他们是同一种类型。

因此基于鸭子类型,之前的代码我们可以稍作简化:class Car:

def run(self):

pass

class Benz:

def run(self):

print("benz run")

class BMW:

def run(self):

print("bwm run")

def run(car):

car.run()

if __name__ == "__main__":

benz = Benz()

bmw = BMW()

run(benz)

run(bmw)

因为在鸭子类型中我们在意的是它的行为,而不是他们的类型;所以完全可以不用继承便可以实现面向接口编程。

总结

我觉得平时没有接触过动态类型语言的朋友,在了解完这些之后会发现新大陆,就像是 Python 老手第一次使用 Java 时;虽然觉得语法啰嗦,但也会羡慕它的类型检查、参数验证这类特点。

动静语言之争这里不做讨论了,各有各的好,鞋好不好穿只有自己知道。

随便提一下其实不止动态语言具备鸭子类型,有些静态语言也能玩这个骚操作,感兴趣下次再介绍。

关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

[Python 中的面向接口编程]http://www.zyiz.net/tech/detail-150944.html

python面向接口编程_Python 中的面向接口编程相关推荐

  1. python 接口编程_Python 中的面向接口编程

    前言 "面向接口编程"写 Java 的朋友耳朵已经可以听出干茧了吧,当然这个思想在 Java 中非常重要,甚至几乎所有的编程语言都需要,毕竟程序具有良好的扩展性.维护性谁都不能拒绝 ...

  2. python接口编程_Python 中的面向接口编程

    前言 "面向接口编程"写 Java 的朋友耳朵已经可以听出干茧了吧,当然这个思想在 Java 中非常重要,甚至几乎所有的编程语言都需要,毕竟程序具有良好的扩展性.维护性谁都不能拒绝 ...

  3. python 编程接口_Python 中的面向接口编程

    前言 "面向接口编程"写 Java 的朋友耳朵已经可以听出干茧了吧,当然这个思想在 Java 中非常重要,甚至几乎所有的编程语言都需要,毕竟程序具有良好的扩展性.维护性谁都不能拒绝 ...

  4. Java中的面向接口编程

    面向接口编程是很多软件架构设计理论都倡导的编程方式,学习Java自然少不了这一部分,下面是我在学习过程中整理出来的关于如何在Java中实现面向接口编程的知识.分享出来,有不对之处还请大家指正. 接口体 ...

  5. 面向接口编程的优点_为什么我们要面向接口编程

    到底面向?编程 面向过程编程( ProcedureOriented.简称 PO) 和 面向对象编程( ObjectOriented.简称 OO) 我们一定听过,然而实际企业级开发里受用更多的一种编程思 ...

  6. java继续_Java中消除实现继续和面向接口编程

    在匆忙之际理清消除实现继续和面向接口编程这样两个大题目可不是一件轻易的事情,尤其考虑到自身的熟悉水平.坦白的说,这又是一篇"炒冷饭"的文章,但这"冷饭"又确实不 ...

  7. 从面向对象编程转为面向接口编程

    大家写过C++或者Java,或者其他语言,基本上都会接触到面向对象这个概念. 面向对象,本身是软件编程发展过程中的产物,当然相比于面向过程,是一种突破性的设计.但是,如果只是停留在面向对象编程,而不是 ...

  8. 黑马java教程是什么_Java教程:揭秘什么是面向接口编程

    先用一个案例来给大家说明一下面向接口编程. 案例:有一个电脑类(Computer),电脑除了有基本的开机关机功能外,还有连接任何外接设备的功能,比如能电脑能连接外置键盘(Keyboard),鼠标(Mo ...

  9. Java面向接口编程,低耦合高内聚的设计哲学

    接口体现的是一种规范和实现分离的设计哲学,充分利用接口可以极大的降低程序中各个模块之间的耦合,提高系统的可维护性以及可扩展性. 因此,很多的软件架构设计理念都倡导"面向接口编程"而 ...

最新文章

  1. 哈啰程序员吐槽:试用期带5个人创造了部门历史最高成绩,结果却被辞退
  2. 手术步骤_做过 激光手术 恢复视力 的人们,后面怎么样呢?
  3. Android 一些比较厉害的大牛博客
  4. HTTP 协议详解(超级经典)
  5. cad抛物线曲线lisp_曲线的转弯半径和曲率 - AutoLISP/Visual LISP 编程技术 - CAD论坛 - 明经CAD社区 - Powered by Discuz!...
  6. Shiro+springboot+mybatis(md5+salt+散列)认证与授权-01
  7. 安卓开发入门到精通!免费Android高级工程师学习资源,系列篇
  8. 做一个常规的banner图——负边距的使用、banner图的拼法
  9. 求小数的某一位(信息学奥赛一本通-T1082)
  10. 100 行 Python 代码实现人体肤色检测
  11. 这样做,免费从Oracle同步数据
  12. pip更新后怎么还是旧版本_微信号不能修改第二次怎么办?微信更新后还是不能修改微信号怎么办?...
  13. ThreadLocal 遇上线程池的问题及解决办法
  14. 基于Android新闻RSS阅读器客户端app
  15. 2018年秋季学期课表
  16. 1-1:Huawei路由交换技术简单知识
  17. 谷歌java模板_如何创建Google表格模板
  18. 【Ubuntu】Ubuntu16.04 安装显卡驱动重启黑屏问题处理
  19. 2015美国大学计算机科学专业排名,2015美国大学本科计算机专业排名前一百
  20. Docker构建基于阿里云epel源的CentOS7 epel源镜像

热门文章

  1. 2018 German Collegiate Programming Contest (GCPC 18)
  2. Apache Cordova for ios环境配置
  3. 设计模式(中介者模式)
  4. 用MDT 2012为企业部署windows 7(十一)--抓取标准模板机镜像
  5. SQL 2005 Oct CTP 和VS2005 for CTP安装的情况
  6. [新功能]定制Blog页面导航区中的链接
  7. java 编写方法和属性,编写一个关于教师的JAVA-BEAN,要求实现其基本属性如年龄,性别等的get和set方法...
  8. ABAP 关于ALV布局保存选项的讲解
  9. NWBC连接配置及使用
  10. 释疑の手工凭证界面不显示页数