When do I have to use interfaces instead of abstract classes?
我想知道什么时候应该使用接口。
让我们考虑一下:
1 2 3 | public abstract class Vehicle { abstract float getSpeed(); } |
还有:
1 2 3 | public interface IVehicle { float getSpeed(); } |
号
我可以很容易地实现它们,它们具有相同的功能…但我也可以在我的Vehicle类中添加一些变量,这些变量可能应该在Vehicle中使用(Maxspeed、CarType…)
使用接口的原因是什么?
谢谢!
编辑:我在另一个线程中找到了一个很好的链接:http://www.thecoldsun.com/en/content/01-2009/abstract-classes-and-interfaces
从Java程序的抽象类:你如何
Because they’re used only as superclasses in inheritance hierarchies,
we refer to them as abstract superclasses. These classes cannot be
used to instantiate objects, because abstract classes are incomplete.
Subclasses must declare the"missing pieces" to become"concrete" classes,
from which you can instantiate objects. Otherwise, these subclasses, too,
will be abstract.
在回答你的问题"什么是使用接口的理由吗?":
An abstract class’s purpose is to provide an appropriate superclass
from which other classes can inherit and thus share a common design.
为反对一个界面:
An interface describes a set of methods that can be called on an
object, but does not provide concrete implementations for all the
methods... Once a class implements an interface, all objects of that class have
an is-a relationship with the interface type, and all objects of the
class are guaranteed to provide the functionality described by the
interface. This is true of all subclasses of that class as well.
这样回答你的问题,我想知道当我应该使用接口",我认为你应该使用时,你需要一个全接口实现和使用抽象类,当你想为你的设计偏块(reusability)
Oracle教程:酒店
不同的接口,抽象类可以包含域是需要
多接口的实现类可以由任何在类的层次,他们是否是在一个相关的办法。认为
通过比较,最常用的是抽象类的子类分享件实现。抽象类是由一单有一个类似的类的子类,在普通钎料(抽象类的实现部分),但也有一些差异(抽象方法)。
许多情况下可以实现在两个类的类型。
接口的定义是有用的当你想有一个有至少类的基本功能。像一个真正的USB接口的一部分。
1 2 3 4 5 | interface USB { public function sendPower(); //charge iphone for example public function sendData(); //itunes public function recieveData(); } |
当我们使用抽象类或对象的方式来实施。
1 2 3 4 5 6 7 8 9 10 11 | abstract class MobilePhone { public function isIphone(); public function charge() { //get some power, all phones need that } } class iPhone extends MobilePhone { public function isIphone() { return true; } } |
有一些你可能会考虑使用时报在实施过抽象接口
- 当可用的摘要的实现不做你想要的和你想创建自己的
- 当你有一个现有的类(这是从其他扩展舱)和你要实现的接口功能
一般说来,人们都在从接口之间的多inheritancy漆,其他的东西
在Java 8启动以来,在接口默认方法的支持下,接口和抽象类之间的差距已经减少,但它们仍然存在重大差异。
接口中的变量是公共静态final。但是抽象类可以有其他类型的变量,如private、protected等
接口中的方法是公共或公共静态的,但抽象类中的方法也可以是私有的和受保护的
使用抽象类建立相关对象之间的关系。使用接口在无关类之间建立关系。
查看Java 8中接口的特殊属性这篇文章。如果要使用@override,接口中默认方法的静态修饰符将导致派生错误中的编译时错误。
本文解释了为什么在Java 8中引入默认方法:增强Java 8中的集合API以支持lambda表达式。
请看一下Oracle文档,以便更好地理解这些差异。
通过代码示例查看这些相关的SE问题,以更好地理解问题:
我应该如何解释接口和抽象类之间的区别?
从Java?教程-与接口相比的抽象类
Which should you use, abstract classes or interfaces?
- Consider using abstract classes if any of these statements apply to your situation:
- You want to share code among several closely related classes.
- You expect that classes that extend your abstract class have many common methods or fields, or require access modifiers other than public (such as protected and private).
- You want to declare non-static or non-final fields. This enables you to define methods that can access and modify the state of the object to which they belong.
- Consider using interfaces if any of these statements apply to your situation:
- You expect that unrelated classes would implement your interface. For example, the interfaces
Comparable andCloneable are implemented by many unrelated classes.- You want to specify the behavior of a particular data type, but not concerned about who implements its behavior.
- You want to take advantage of multiple inheritance of type.
An example of an abstract class in the JDK is
AbstractMap , which is part of the Collections Framework. Its subclasses (which includeHashMap ,TreeMap , andConcurrentHashMap ) share many methods (includingget ,put ,isEmpty ,containsKey , andcontainsValue ) thatAbstractMap defines.
号
当您希望为一组子类定义模板时,请使用抽象类,并且至少可以使用一些调用子类的实现代码。
当您想定义其他类可以扮演的角色时,不管这些类在继承树中的位置如何,都可以使用接口。
扩展抽象类
实现接口:)
在一个接口中,所有字段都自动为
这个问题的答案很简单,无论我们用接口做什么,都可以用抽象类agree来完成……所以当使用接口时,答案在于对多重继承的C限制。当你只有契约(抽象)来声明并希望你的子类实现它与接口一起使用时,因为如果你在这种情况下使用抽象类,你不能从一个类继承,如果你想从一个类继承,你会被卡住,但是你可以实现尽可能多的接口。
这是Bruce Eckel的优秀著作《Java思维》的直接摘录。
[..] Should you use an interface or an abstract class?
Well, an interface gives you the benefits of an abstract class and the benefits of an interface, so if it’s possible to create your base class without any method definitions or member variables you should always prefer interfaces to abstract classes.
In fact, if you know something is going to be a base class, your first choice should be to make it an interface, and only if you’re forced to have method definitions or member variables should you change to an abstract class.
号
如果您使用的是JDK8,那么就没有理由使用抽象类,因为无论我们对抽象类做什么,现在我们都可以使用接口,因为使用了默认方法。如果使用抽象类,则必须对其进行扩展,并且存在只能扩展一次的限制。但是,如果您使用接口,那么您可以实现任意多的接口。
默认情况下,接口是一个抽象类,所有方法和构造函数都是公共的。
与Java:
接口:
- 是一个基本的面向对象的抽象。
- 要经常(但并不总是)收益率虽然比抽象类的代码。
- 可以实现多个不同的混凝土类集的情况。
- CAN实现多重继承的情况下直接调用。
- 可以更容易mocked退出测试的用途。
- useful for JDK代理(湖是java.lang.reflect.proxy)。
这些只是开始,一个很长的清单生成的接口和抽象类。
抽象类包含抽象方法是需要的CAN接口,而在所有的摘要方法是一定要实现的。
你应该使用接口而不是当你知道你将永远是实现这些方法。所以,你可以继承多个接口,它是Java的方式处理与多重继承
接口基本上是两方的作品一起使用时,一方隐藏的东西从我的其他(或只想显示他的一部分,我们使用接口类).than EC。在JDBC JDBC供应商为我们提供了一些接口,因为他们想隐藏在美国的一切。
抽象类是唯一的案例中使用的是当我们要支持一个普通的行为。一类或想提供一些preimplemented实施方法(方法和一些unimplemented应摘要)。在Servlet的HTTP Servlet)。因为这是一个抽象类接口实现Servlet接口的类,除了它是这类服务的方法帮助我们得到一些preimplemetation)接口的方法。
使用抽象类不能实现多重继承,这就是Sun Microsystems提供接口的原因。
不能扩展两个类,但可以实现多个接口。
接口提供
抽象类提供了
当我们希望一个类型的所有功能都由客户机实现时,可以使用
当
抽象类:当有很强的is-a关系时使用,超类和子类都有一些共同的行为。
接口:它只定义所有子类都需要遵循的协议。
实际上,接口和抽象类只是用来指定一些契约/规则,这些契约/规则只显示它们的子类是如何的。
我们大多知道接口是纯抽象的,这意味着你不能用主体来指定一个方法,这一点是抽象类的优点,也就是说在抽象类中,你有权指定有主体和没有主体的方法。
所以如果你想指定一些关于你的子类的内容,那么你可以选择接口。但是如果你还想为你的子类指定一些东西,你也希望你的类也有一些自己的方法,那么在这种情况下,你可以选择抽象类。
接口和抽象类看起来非常相似,但是它们之间有重要的区别。
抽象是基于一个良好的"IS-A"关系。这意味着你会说一辆车是本田,而本田是一辆车。在类上使用抽象意味着您也可以拥有抽象方法。这将需要从中扩展的任何子类来获取抽象方法并重写它们。使用下面的示例,我们可以创建一个抽象的howtoStart();方法,该方法需要每个类来实现它。
通过抽象,我们可以提供代码之间的相似性,这样我们仍然有一个基类。使用汽车类概念的示例,我们可以创建:
1 2 3 4 5 6 7 8 9 10 11 12 |
那么,如果是本田,我们将拥有:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
号
接口基于"has-a"关系。这意味着你可以说一辆车有一个发动机,但发动机不是一辆车。在上面的例子中,本田有
对于引擎接口,我们可以创建:
1 2 3 | public interface Engine { public void startup(); } |
接口将提供多对一实例。所以我们可以将引擎接口应用于任何类型的汽车。我们也可以将其扩展到其他对象。就像我们要做一个船类,并且有船类型的子类一样,我们可以扩展引擎,让船的子类需要
1 | public class Honda extends implements Engine, Transmission, List<Parts> |
。
希望这有帮助。