接口/抽象类的思考
接口中只能定义常量,声明方法(不可以实现)? 意义何在?
这是一道面试题,有些人可能拿到这到题就会困惑,接口里声明的都是常量,这是j2se里规定,还有什么理由吗?确实在我看到这到问题的时候也是这么想的,但仔细一考虑也发现这道的意义所在。
接口中不允许方法的实现,而抽象类是允许方法实现的及定义变量的,因此我们可以看出接口是比抽象类更高层次的抽象。如果接口可以定义变量,但是接口中的方法又都是抽象的,在接口中无法通过行为(例如set()方法)来修改属性。那么有些人就会提出可以通过实现接口的类的实例来修改接口的属性。那好,如果接口中有一变量c,我们通过实现它的A类对象改变了c的值,那么实现接口的B类,C类中的c变量都要跟着改变,可想而知这样就会造成混乱,很多想要实现接口的类就不知道接口里现在c变量到底是什么值,因为接口是在变的,它不再是那种高层的抽象,而是带了可变的成分。所谓的抽象就是把一些不可变的东西放在一起,而可变的东西往往放在实现里面。
所以我们深思接口的本意所在,实际上它是对一类事物属性和行为的高层次抽象,它体现的是OCP(对修改关闭,对扩展开放)原则,这也是我们软件开发中一直所追求。
为什么在接口中定义成员变量会报错,为什么在接口中实现方法会报错?
抽象类就可以声明方法并实现!为什么接口不可以?why,why,why???
想知道为什么,就要先了解oop思想中的ocp (Open-Close Principle)原则.
OOP最大的弊端,就是很多程序员已经忘记了OOP的初心,潜意识中把OOP教条主义化(如同对GOTO语句的禁忌一般),而不是着眼于OOP着力达到的、更本质的目标,如:
- 改善可读性
- 提升重用性
但是OOP最重要的目标,其实是OCP,即「开闭原则」。这一点很多答案都没有提到。
这就是为什么会有「用多态代替switch」的说法。在应该使用多态的地方使用switch,会导致:
1 - 违反「开放扩展」原则。假如别人的switch调用了你的代码,你的代码要扩展,就必须在别人的代码里,人工找出每一个调用你代码的switch,然后把你新的case加进去。
2 - 违反「封闭修改」原则。这是说,被switch调用的逻辑可能会因为过于紧密的耦合,而无法在不碰switch的情况下进行修改。
但是OCP不是免费的。如果一个模块根本没有扩展的需求,没有多人协作的需求,花时间达成OCP又有什么意义呢?设计类关系的时候忘记了OOP的初心,可能就会写出很多没有帮助的类,白白浪费人力和运行效率。
所以,假如所有代码都是你一个人维护,没有什么扩展的需求,那么多用一些switch也未尝不可;假如你的代码是要被别人使用或者使用了别人的代码,OOP很可能就是你需要用到的工具。
除了OOP,Type class和Duck Typing都是可以帮助你达成OCP原则的工具。当然,如果你使用的语言是Java,这两种工具都不用想了。作者:施行
链接:https://www.zhihu.com/question/20275578/answer/26548179
来源:知乎