接口和抽象类之间到底有什么区别?


当前回答

接口与抽象类的比较是错误的。应该有另外两个比较:1)接口与类,2)抽象与最终类。

接口与类

接口是两个对象之间的契约。例如,我是一名邮递员,而你是一个要递送的包裹。我希望你知道你的送货地址。当有人给我一个包裹时,它必须知道它的送货地址:

interface Package {
  String address();
}

类是一组遵守契约的对象。例如,我是“箱子”小组的一名箱子,我遵守邮递员要求的合同。同时,我遵守其他合同:

class Box implements Package, Property {
  @Override
  String address() {
    return "5th Street, New York, NY";
  }
  @Override
  Human owner() {
    // this method is part of another contract
  }
}

摘要与最终

抽象类是一组不完整的对象。它们不能使用,因为它们缺少一些部件。例如,我是一个抽象的GPS感知框-我知道如何检查我在地图上的位置:

abstract class GpsBox implements Package {
  @Override
  public abstract String address();
  protected Coordinates whereAmI() {
    // connect to GPS and return my current position
  }
}

这个类如果被另一个类继承/扩展,可能非常有用。但就其本身而言,它是无用的,因为它不能有对象。抽象类可以是最终类的构建元素。

Final类是一组完整的对象,可以使用,但不能修改。他们确切地知道如何工作和做什么。例如,我是一个盒子,它总是在构建过程中到达指定的地址:

final class DirectBox implements Package {
  private final String to;
  public DirectBox(String addr) {
    this.to = addr;
  }
  @Override
  public String address() {
    return this.to;
  }
}

在大多数语言中,如Java或C++,可能只有一个类,既不是抽象类也不是最终类。这样的类可以继承并实例化。不过,我认为这并不严格符合面向对象的范例。

同样,将接口与抽象类进行比较是不正确的。

其他回答

抽象类和接口之间的关键技术差异是:

抽象类可以有常量、成员、方法存根(没有主体的方法)和定义的方法,而接口只能有常量和方法存根。抽象类的方法和成员可以以任何可见性定义,而接口的所有方法都必须定义为public(默认情况下定义为public)。继承抽象类时,具体的子类必须定义抽象方法,而抽象类可以扩展另一个抽象类,父类的抽象方法不必定义。类似地,扩展另一个接口的接口不负责从父接口实现方法。这是因为接口不能定义任何实现。子类只能扩展一个类(抽象或具体),而接口可以扩展或类可以实现多个其他接口。子类可以定义具有相同或更少限制性可见性的抽象方法,而实现接口的类必须定义具有完全相同可见性(公共)的方法。

当您想在继承层次结构中提供多态行为时,请使用抽象类。

当您想要完全无关的类的多态行为时,请使用接口。

在实用性方面(JAVA),抽象类和接口之间的主要区别是抽象类可以保存状态。除了保持状态,我们还可以使用Interface实现其余操作。

界面:转弯(左转,右转)

抽象类:轮子。

类别:方向盘,衍生自方向盘,暴露接口转向

一个是对可以在各种各样的事物中提供的行为进行分类,另一个是为事物本体建模。

其实很简单。

您可以将接口视为一个类,它只允许有抽象方法,而不允许有其他方法。

因此,接口只能“声明”而不能定义您希望类具有的行为。

抽象类允许您声明(使用抽象方法)和定义(使用完整方法实现)您希望类具有的行为。

常规类只允许您定义而不是声明您希望类具有的行为/动作。

最后一件事,

在Java中,可以实现多个接口,但只能扩展一个(抽象类或类)。。。

这意味着定义行为的继承被限制为每个类只允许一个。。。例如,如果你想要一个从类a、B和C中封装行为的类,你需要执行以下操作:类a扩展B,类C扩展a。。这是一个有点迂回的方式来拥有多重继承。。。

另一方面,您可以简单地执行接口:接口C实现A、B

因此实际上,Java只在“声明的行为”(即接口)中支持多重继承,并且只支持具有定义行为的单一继承。。除非你像我描述的那样。。。

希望这是合理的。