你好,你的问题包含了两个小问题,①java设计interface的原因?②是不是为了尽可能替代类的继承?
接口与继承分别是什么?(定义)接口是一系列方法的声明,比如方法名、参数、返回值等信息,接口中的方法不实现,这些方法可以在不同的地方被不同的类实现。
继承就是子类继承父类的特征和行为,使得子类具有父类的实例域和方法。
接口与继承的设计原因是什么?(用处)接口的主要作用在于降低代码的耦合度,屏蔽实现层,比如前后端接口交互的时候,大家约定好接口层就可以互不影响的干活了,至于接口实现后端可以慢慢做。
继承的主要作用在于,在已有基础上继续进行功能的扩充①清晰体现相关类间的层次结构关系②减小代码的冗余度,大大增加程序的重用性。
接口与继承有什么区别?①定义的修饰符不同(interface),(extends)
②接口中只能定义全局常量和抽象方法,而在继承中可以定义属性方法,变量,常量等。
③接口被类实现时,在类中一定要实现接口中的所有方法,而继承可以调用指定方法。
④继承只能继承一个类,但implements可以实现多个接口,用逗号分开就行了 。
综上所述,java中接口与类继承各有自己存在的原因,有自己的适用场合,有区别也有一定的联系,可以根据自己的具体需求来选择。
继承代价太大,强制你把父类的所有东西都拿过来,不然就不准使用,这种将方法和属性强耦合的方式容易导致类继承多了到后面积重难返。使用鸭子类型(接口)能避免一部分继承的缺陷,go里甚至直接继承都没有了,只有接口。
以前我们把物体抽象,大象抽象是动物,动物抽象是生物,这样本身就把对象的内容和行为绑定了,比如大象会喷水,就给大象加个喷水的方法,但是如果鱼也会喷水,喷水这个方法又不能放到动物类里,那么基于大象和鱼的喷水方法实现的上层方法就无法复用,这两个喷水在编译器看来是没有任何关系的。
开始人们想到搞一个喷水动物类,继承动物类,大象和鱼再继承喷水动物类。但是这样终究治标不治本,再有其他的变化,继承链又要修改。
因为实际上我们使用对象,都是在使用其方法(属性其实也应该算方法)。
我对面向对象程序过程的理解,这个过程实际上就是让对象之间使用方法互发消息进行通信和动作,最终完成工作。
大家都知道的一句话,上层应该依赖抽象而不是依赖细节,然而依赖一个基类,本身已经依赖这个基类的实现细节,基类要求有个int成员,那么任何子类无论如何都需要有个int成员。那么理应将方法抽象出来,而不去关心其到底是什么,因为我们并不使用对象内部的内容,我们只使用方法。
比如有个iwriteable接口,表示对象可以按字节写入,那么上层的代码就不用管写的到底是什么了,只要能写就行,就可以基于这个iwriteable接口里的方法,写出例如写字符串,写图片等方法。任何实现了这个接口的类,都可以复用这些写字符串,写图片的代码。
那么就有人要问了,那如果我确实要求要有个int成员,因为我上层代码要使用呢?那么根据前面说的,属性也是方法,你应该再定义一个接口,比如这个int存的是年龄,那么就来个haveage接口并实现它。调用的地方可以要求对象实现哪几个接口,这样也能获取需要的属性。
这么一来,连属性都没有了,那么继承也可以没有了,毕竟你要求的不是基类了,是一个或多个接口的组合了,所以你可以看到,接口替代继承是很自然的,而不是什么刻意而为的,是更高级抽象的体现。事实上基于自然规则的那套大象是动物,动物是生物的那套面向对象规则,在程序设计里并不好用。所以如果让我介绍面向对象,我不会讲这些例子。
这个问题很有意思。虽然有一些场景,使用继承和接口都可以实现,但是接口的存在绝对不仅仅是代替类的继承。
首先继承和接口的区别很明显,用通俗的话来讲,接口好比一个人的老师,会告诉你要做什么(实现接口要实现接口中的方法),而继承就好比是亲爹,会把所有的都给你(子类可以调用父类提供的方法),一个人可以有多个老师,但是只有一个亲爹(接口可以实现多个,类只可以继承一个)。
那么再来说说接口存在的意义。简单的理解在Java中接口相当于是定义了规范,而这些规范可以严格控制每个实现的功能。最明显的应用就是JavaEE,JavaEE中只定义了各种接口,并没有实现,而我们平时所使用的基本都是一些实现了这些接口的第三方类,比如tomcat的。
另外接口的存在也使得应用的可维护性和扩展性变得更强,比如,在一个应用中使用了MySQL数据库,然后未来某一时间想要更换成其他数据库,那么就只需要学一个其他数据库的类实现数据库接口就可以无缝切换了。
此外还有一个很重要的点,接口是Java程序中解耦的重要手段。相反的类的继承是确实增加了耦合度。
所以说,Java中接口的存在是很有必要的。