我何时必须使用接口而不是抽象类?

我想知道什么时候应该使用接口。

让我们思考以下几点:

public abstract class Vehicle { abstract float getSpeed(); } 

和:

 public interface IVehicle { float getSpeed(); } 

我可以很容易地实现他们两个,他们有相同的function…但我也可以添加一些variables,我的车辆类,这可能应该用在车辆(maxSpeed,carType …)

什么是使用接口的原因?

谢谢!

编辑:我发现了另一个线程中的一个不错的链接: http : //www.thecoldsun.com/en/content/01-2009/abstract-classes-and-interfaces

从Java如何编程抽象类:

因为它们只被用作inheritance层次结构中的超类,所以我们把它们称为抽象超类。 这些类不能用于实例化对象,因为抽象类是不完整的。 子类必须声明“缺less的部分”成为“具体”类,从中你可以实例化对象。 否则,这些子类也是抽象的。

回答你的问题“使用接口的原因是什么?”:

抽象类的目的是提供一个适当的超类,其他类可以inheritance,从而共享一个共同的devise。

与界面相反:

一个接口描述了一组可以在一个对象上调用的方法,但是并没有为所有的方法提供具体的实现 …一旦一个类实现了一个接口,那么这个类的所有对象都与接口types具有is-a关系并且该类的所有对象都保证提供接口描述的function。 这个类的所有子类也是如此。

所以,要回答你的问题“我想知道什么时候应该使用接口”,我想你应该使用接口,当你想要一个完整的实现,并使用抽象类,当你想为你的devise部分件(为可重用性)

从Oracle教程 :

与接口不同, 抽象类可以包含非 staticfinal 字段 ,并且可以包含实现的方法。 这样的抽象类与接口类似,不同之处在于它们提供了部分实现,而将其留给子类来完成实现。 如果抽象类仅包含抽象方法声明,则应该将其声明为接口。

可以通过类层次结构中任何位置的类来实现多个接口 ,无论它们是否以任何方式相互关联。 例如,考虑可Comparable或可Cloneable

相比之下, 抽象类通常被分类以分享实现 。 一个抽象类被类似的类所分类,这些类有很多共同点(抽象类的实现部分),但也有一些不同(抽象方法)。

你应该使用哪个抽象类或接口?

如果这些语句适用于您的情况, 请考虑使用抽象类

你想在几个密切相关的类中分享代码。

您期望扩展抽象类的类具有许多常用的方法或字段,或者需要公共访问修饰符(例如protected和private)。

您想要声明非静态或非最终字段。 这使您可以定义可以访问和修改它们所属对象状态的方法。

如果以下任何一种语句适用于您的情况, 请考虑使用接口

你期望不相关的类将实现你的接口。 例如,Comparable和Cloneable接口是由许多不相关的类实现的。

您想要指定特定数据types的行为,但不关心谁实现其行为。

你想利用types的多重inheritance。

许多情况下都可以在两个类中实现。

当你想定义一个至less具有基本function的类时,接口是有用的。 就像一个真正的接口,例如USB。

 interface USB { public function sendPower(); //charge iphone for example public function sendData(); //itunes public function recieveData(); } 

当有几种方法来实现对象时使用抽象类。

 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; } } 

有很多次您可能会考虑通过抽象实现来使用接口

  • 当可用的抽象实现不能做你想要的,你想创build自己的
  • 当你有一个现有的类(从其他类扩展),你想实现接口的function

一般来说,介绍接口是为了克服缺乏多重inheritance等

自Java 8发布以来,在接口中默认方法的支持下,接口类和抽象类之间的差距已经减小,但是它们仍然存在很大差异。

  1. 接口中的variables是public static final 。 但是抽象类可以有其他types的variables,如private,protected

  2. 接口中的方法是publicpublic static,但抽象类中的方法也可以是privateprotected

  3. 使用抽象类来build立相关对象之间的关系。 使用接口build立无关类之间的关系。

看看这篇文章的特殊属性的接口在Java 8中。静态修改器的默认方法在接口导致编译时错误导出错误,如果你想使用@覆盖。

本文解释了为什么在java 8中引入了默认方法: 为了增强Java 8中的Collections API以支持lambdaexpression式。

看一下oracle文档也是为了更好的理解差异。

用代码示例来看看这个相关的SE问题来更好地理解事物:

我应该如何解释一个接口和一个抽象类的区别?

引用博客: https : //mybolder.com/2015/12/02/when-to-use-abstract-class-and-intreface/

你应该使用哪个抽象类或接口?

如果这些语句适用于您的情况,请考虑使用抽象类:

  1. 你想在几个密切相关的类中分享代码。
  2. 您期望扩展抽象类的类具有许多常用的方法或字段,或者需要公共访问修饰符(例如protected和private)。
  3. 您想要声明非静态或非最终字段。 这使您可以定义可以访问和修改它们所属对象状态的方法。

如果以下任何一种语句适用于您的情况,请考虑使用接口:

  1. 你期望不相关的类将实现你的接口。 例如,Comparable和Cloneable接口是由许多不相关的类实现的。
  2. 您想要指定特定数据types的行为,但不关心谁实现其行为。
  3. 你想利用types的多重inheritance。

JDK中的抽象类的一个例子是AbstractMap ,它是Collections Framework的一部分。 它的子类(包括HashMapTreeMapConcurrentHashMap )共享AbstractMap定义的许多方法(包括getputisEmptycontainsKeycontainsValue )。

考虑到Java:

接口:

  • 是一个基本的面向对象抽象。
  • 经常(但不总是)比抽象类产生更清晰的代码。
  • 可以通过多个具体的类来实现,以适应不同的情况。
  • 可以直接实现调用多重inheritance的场景。
  • 可以更容易地嘲笑出于testing目的。
  • 对JDK代理有用(请参阅java.lang.reflect.Proxy)。

这些仅仅是界面与抽象类的优点/缺点列表的开始。

这是Bruce Eckel出色的书“ Thinking in Java ”的直接摘录。

[…]你应该使用一个接口还是一个抽象类

那么,一个接口给你一个抽象类的好处和一个接口的好处,所以如果可以创build你的基类没有任何方法定义或成员variables,你应该总是喜欢接口抽象类。

事实上,如果你知道什么是基类,你的第一select应该是把它变成一个接口,并且只有当你被强制拥有方法定义或者成员variables的时候,你才应该把它变成一个抽象类。

当你想为一组子类定义一个模板时,使用一个抽象类,并且至less有一些调用子类的实现代码可以使用。

如果要定义其他类可以播放的angular色 ,请使用接口而不pipe这些类在inheritance树中的位置

扩展一个抽象类

实现一个接口:)

在一个接口中,所有的字段都是自动public static final ,所有的方法都是public抽象类允许你在这里有一些灵活性。

抽象类可以包含非抽象的方法,而在接口中,所有的方法都是抽象的,必须实现。

你应该使用接口,而你知道你总是会实现这些特定的方法。 你也可以从多个接口inheritance,这是java处理多重inheritance的方法

界面基本上是在双方协同工作时使用的,一方要隐藏其他方面的东西(或者只想显示他的一部分)。 在jdbc jdbc供应商提供给我们一些接口bcoz他们想要隐藏我们所有的东西。

抽象类只在这种情况下使用,当我们要支持一个以上的类的共同行为…或者想提供一些未实现的方法(方法应该是抽象的)的预先实现的实现。 例如。 servlet接口中的http servlet是一个抽象类bcoz这个类实现了servlet接口,除了它的服务方法…所以这个类帮助我们得到一些接口方法的preimplemetation …

其实Interface和抽象类只是用来指定一些合约/规则,这些合约/规则只会显示其子类将如何。

大多数情况下,我们知道接口是一个纯粹的抽象。意味着你不能指定一个单一的方法与body.This特别的一点是抽象类的优点。抽象类中的手段有权指定方法与身体和身体没有好。

所以,如果你想指定关于你的子类的东西,那么你可以去接口。 但是,如果你也想为你的子类指定一些东西,你也希望你的类也应该有自己的方法。那么在这种情况下,你可以去抽象类

你不能实现与抽象类的多重inheritance,这就是为什么太阳微系统提供接口。

您不能扩展两个类,但可以实现多个接口

InterfaceAbstract Class是实现OOP语言抽象的两种不同方式。

接口提供了100%抽象,即所有的方法都是抽象的。

抽象类提供了0 to 100%抽象,即它可能有或没有抽象方法。

当我们希望客户端实现一个types的所有function时,我们可以使用Interface

Abstract Class实现者可以提供一些通用的function时,我们可以使用Abstract Class ,客户端将有机会实现他实际需要的东西。

抽象类 :当强壮的时候使用它是超类和子类的关系,而所有的子类都有一些共同的行为。

接口 :它定义了所有子类需要遵循的协议。

这个问题的答案很简单,无论我们能用接口做什么,都可以用抽象类Agree来完成……所以何时使用接口,答案就在于C#对多重inheritance的限制。 当你只有合同(摘要)来声明,并希望你的子类实现它与接口,因为如果你在这种情况下使用抽象类,你不能从一个类inheritance,你被卡住,如果要从一个inheritance更多的类,但你可以实现尽可能多的接口。

如果您使用的是JDK 8,那么就没有理由使用抽象类,因为无论我们使用抽象类,我们现在都可以使用接口来执行它,因为使用了默认方法。 如果你使用抽象类,你必须扩展它,并且有一个限制,只能扩展一次。 但是,如果你使用接口,你可以实现尽可能多的,你想要的。

接口默认是一个抽象类,所有的方法和构造函数都是公共的。

接口和抽象类看起来非常相似,但是它们之间有重要的区别。

抽象是build立在一个好的“ ”关系的基础上的。 这意味着你会说一辆汽车是本田,而本田是一辆汽车。 对类使用抽象意味着你也可以有抽象方法。 这将需要从它扩展的任何子类来获取抽象方法并覆盖它们。 使用下面的例子,我们可以创build一个抽象的howToStart(); 方法,这将需要每个类来实现它。

通过抽象,我们可以提供代码之间的相似性,所以我们仍然有一个基类。 以Car类的想法为例,我们可以创build:

 public abstract class Car{ private String make; private String model protected Car() { } // Default constructor protect Car(String make, String model){ //Assign values to } public abstract void howToStart(); } 

然后,与本田class,我们会有:

 public class Honda extends implements Engine { public Honda() { } // Default constructor public Honda(String make, String model){ //Assign values } @Override public static void howToStart(){ // Code on how to start } } 

接口基于“有-a”关系。 这意味着你可以说一辆车有一台发动机,但是一台发动机不是一辆汽车。 在上面的例子中,本田已经implements Engine

对于引擎接口,我们可以创build:

 public interface Engine { public void startup(); } 

该界面将提供多对一的实例。 所以我们可以将引擎接口应用于任何types的汽车。 我们也可以把它扩展到其他对象。 就像我们要做一个船class,并且有一些船的子类,我们可以扩展Engine,并且让子类的船需要startup(); 方法。 接口对于为具有一些相似性的各种类创build框架是很好的。 我们也可以在一个类中实现多个实例,比如:

 public class Honda extends implements Engine, Transmission, List<Parts> 

希望这有助于。

如果您的Interface方法实现对所有Inherting类都是相同的,那么您不需要接口,而应该使用Abstract类。 当你想要某个东西被每个类(必须)跟随,那里的实现将会有所不同或者没有被定义,那么我们去接口。