隐式接口实现(ImplicitInterfaceImplementation)
译自:Martin Fowler's Bliki 2006.01.04
EN:ImplicitInterfaceImplementation
JP:暗黙的インタフェースの実装
Java和C#拥有同样的模型:单纯接口类型(pure interface types)[注1]
. 我们可以声明一个Pure Interface使用这样的代码:
Interface
Mailable, 接着我们也可以定义他的一个实现:class Customer implements Mailable (in Java).
一个类可以实现多个Pure Interface.
这一模型存在一个问题,他忽略了这样一个事实: 一旦我们拥有了一个Class, 那么我们便拥有了一个与之相应的隐式接口(Implicit Interface). 以上述的Customer类为例, 其隐式接口是指在Customer中声明的所有Public方法所组成的接口(这种隐式接口的概念在我所见过的OO语言中,都存在).使用Java也好, C#也好, 实现一个隐式接口是办不到的, 也就是说我们不能写出形如下面这样的代码:"Class ValuedCustomer implements Customer".
实现一个隐式接口是什么意思呢?本质上, 他将告诉类型系统, 类ValuedCustomer实现了Customer类中声明的所有public方法,并忽略了他的实现. Customer类的实现包括, 其public方法的实现, 非public方法,以及数据. 也就是说我们拥有了接口继承, 而非实现继承.
拥有隐式接口的这样一个Customer类, 就如同我们拥有了两个东西, 其一是"Customer接口", 该接口里面含有Customer类的所有Public方法, 其二是一个"CustomerImpl"类, 他实现了"Customer接口".
隐式接口这一特性会给我们带了什么便利?
答案之一是在Java的初期, 因为还没有现在这样的Collections框架, 所以我经常想将Vector替换成我自己的实现。但是很遗憾,我们办不到,因为Vector是一个类,我们只能子类化他。我曾一次次的遭遇这样的场面,只是因为我使用的库并没有给我提供相应的接口,以允许我切换实现。是的,没有隐式接口实现,我们没发做到这些。
另一个特别的原因是测试问题, 因为没有接口, stub的时候常常很难, 甚至不可能。这种情况下,我们经常只是为了将来能够进行替换实现,而去定义了一个接口。这种InterfaceImplementationPair方法,能解决这个问题。但是我更喜欢隐式接口实现,因为他更加清晰易读。
但是,为什么编程语言没有允许这一特性呢?我不知道,因为我不是一个语言设计者。但有一次,我有机会与Anders Heljsberg[注2]
讨论这一问题,得到的答案是他更偏好于:“只有你显示的声明了一个成员为Virtual,你才可以对他进行覆写(overriding)”[注3]
。这实质上是担心子类(或者实现者,更确切的说)会破坏其父类,这涉及到如何使用继承,他只适合晚餐后来讨论,这里我不打算详细说明。
这一问题在动态语言中不存在,其他的类如果想实现一个对象的接口时,只需要实现与该对象相同的方法即可。在Java中的动态代理也是解决该问题的一个方法,尽管我认为隐式接口实现要更清晰可读。
Mike Rettig指出了隐式接口实现的一个问题:并非所有的用户都只使用类的Public方法。试想PaymentPlan与Customer类在同一个包中,那么他可以调用Customer类中具有包可见性的方法。那么如果使用Customer的一个隐式接口实现的类,去替换Customer类,PaymentPlan便会出错(译注:因为拿去替换的类已经不再拥有Customer类中具有包可见性的方法)。
Mike Rettig指出的问题是:一个类有多个隐式接口,同时每一个隐式接口又有不同的访问权限控制(译注:包可见性方法与public可见性方法便不完全在同一隐式接口中)。同样的一个类,对其他某些实例,会允许范围更广的访问。
注1:为了与ImplictInterface想对应,我本想把这里翻译成显示接口,但为了与原为对应,这里翻译成了单纯,日语中被翻译成了纯粹。
注2: Anders Heljsberg
: turbo pascal, delphi, C#等的作者
注3: 这句话我的理解是,1.隐式的接口继承确实会舍弃一些父类一些东西(属性,非public方法,public方法的实现),这当然是对父类的一种破坏。2. 对于"只有显示声明为Virtual,才能进行覆写"这句话,我理解他也是对“子类不破坏父类”的一种保护,因为如果如果父类的作者不显示声明为Virtual,那么你便不可以对该方法覆写,进而你也无法展开多态。此时程序的设计者拥有更多的控制权(责任)。
分享到:
相关推荐
Jupyter-Notebook
Jupyter-Notebook
高效甘特图模板下载-精心整理.zip
lstm Summary Framework: z = U>x, x u Uz Criteria for choosing U: • PCA: maximize projected variance • CCA: maximize projected correlation • FDA: maximize projected intraclass variance
OpenGL调试工具,适合图形开发者,包括视频开发,播放器开始以及游戏开发者。
全国行政区划shp最新图.zip
全国研究生招生与在校数据+国家线-最新.zip
Jupyter-Notebook
直播电商交流平台 SSM毕业设计 附带论文 启动教程:https://www.bilibili.com/video/BV1GK1iYyE2B
《林黛玉进贾府》课本剧剧本
2000-2020年沪深A股上市公司融资约束程度SA指数-最新数据发布.zip
PPT模版资料,PPT模版资料
CPA注会考试最新教材资料-最新发布.zip
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
内容概要:本文提供了一个完整的职工管理系统的C++源代码。通过面向对象的编程方法,实现了包括创建新职工、查询、增加、修改、删除、排序、统计以及存储和恢复职工数据在内的多个基本操作功能。该系统支持不同的用户角色(如管理员与老板),并通过菜单驱动方式让用户方便地进行相关操作。此外,还包括了错误检测机制,确保操作过程中的异常得到及时处理。 适合人群:有一定C++语言基础,特别是面向对象编程经验的程序员;企业管理人员和技术开发人员。 使用场景及目标:适用于中小型企业内部的人力资源管理部门或IT部门,用于维护员工基本信息数据库,提高工作效率。通过本项目的学习可以加深对链表、类和对象的理解。 阅读建议:建议先熟悉C++的基本语法和面向对象概念,再深入学习代码的具体实现细节。对于关键函数,比如exchange、creatilist等,应当重点关注并动手实践以加强理解。
Jupyter-Notebook
考研公共课历年真题集-最新发布.zip
Huawei-HKUST Joint Workshop on Theory for Future Wireless 15-16 September 2022 华为-香港科技大学未来无线理论联合研讨会 Speaker:Jingwen Tong
演出人员与观众疫情信息管理系统 SSM毕业设计 附带论文 启动教程:https://www.bilibili.com/video/BV1GK1iYyE2B
《林黛玉进贾府》课本剧剧本.pdf