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


当前回答

之所以调用接口,是因为它向调用方(例如COM客户端)提供了由某个类实现的方法接口。通过将一个对象指针以多态的方式投射到对象类实现的接口的类型,它限制对象对其实现的接口中的函数和成员的访问,与coclass可能实现的其他COM接口分离。客户端不需要知道什么类实现了接口,或者该类中存在什么其他方法;对象以它所知道的接口实例的形式呈现(其中类的实例已被多态地转换为接口实例,该接口实例是类的子实例),它只是通过调用接口实例上的接口方法来使用接口。实际实现的所有细节和不同接口实现的无关功能/细节都与调用方期望的接口分离——调用方只使用它与对象的接口(接口实例及其作为对象一部分的虚拟表指针),并且调用底层对象实现,而调用者不必知道实现的位置或细节。通过接口(接口类型的指针)访问对象是一种封装形式,在语法上防止未经授权访问对象,并隐藏实现细节和其他与接口及其定义的个性无关的功能。

接口是所有方法都是虚拟和抽象的(抽象在C++中称为纯虚拟;所有抽象方法都包含虚拟说明符,因此是虚拟的)。抽象类是指至少有一个方法是虚拟的,并指定为抽象的(或C++中的纯虚拟)。其他细节因语言而异。所有的接口属性在java中都是隐式的公共静态final,但在C++中不是。Java允许在抽象类中使用非静态属性,但C++允许在两者中使用它们。两种语言中的属性都不能是虚拟/抽象的。

其他回答

接口与抽象类的比较是错误的。应该有另外两个比较: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++,可能只有一个类,既不是抽象类也不是最终类。这样的类可以继承并实例化。不过,我认为这并不严格符合面向对象的范例。

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

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

抽象类:轮子。

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

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

接口只包含功能的定义/签名,如果我们有一些公共功能和公共签名,那么我们需要使用抽象类。通过使用抽象类,我们可以同时提供行为和功能。另一个继承抽象类的开发人员可以很容易地使用这个功能,因为他们只需要填写空白。

摘自:

http://www.dotnetbull.com/2011/11/difference-between-abstract-class-and.html

http://www.dotnetbull.com/2011/11/what-is-abstract-class-in-c-net.htmlhttp://www.dotnetbull.com/2011/11/what-is-interface-in-c-net.html

之所以调用接口,是因为它向调用方(例如COM客户端)提供了由某个类实现的方法接口。通过将一个对象指针以多态的方式投射到对象类实现的接口的类型,它限制对象对其实现的接口中的函数和成员的访问,与coclass可能实现的其他COM接口分离。客户端不需要知道什么类实现了接口,或者该类中存在什么其他方法;对象以它所知道的接口实例的形式呈现(其中类的实例已被多态地转换为接口实例,该接口实例是类的子实例),它只是通过调用接口实例上的接口方法来使用接口。实际实现的所有细节和不同接口实现的无关功能/细节都与调用方期望的接口分离——调用方只使用它与对象的接口(接口实例及其作为对象一部分的虚拟表指针),并且调用底层对象实现,而调用者不必知道实现的位置或细节。通过接口(接口类型的指针)访问对象是一种封装形式,在语法上防止未经授权访问对象,并隐藏实现细节和其他与接口及其定义的个性无关的功能。

接口是所有方法都是虚拟和抽象的(抽象在C++中称为纯虚拟;所有抽象方法都包含虚拟说明符,因此是虚拟的)。抽象类是指至少有一个方法是虚拟的,并指定为抽象的(或C++中的纯虚拟)。其他细节因语言而异。所有的接口属性在java中都是隐式的公共静态final,但在C++中不是。Java允许在抽象类中使用非静态属性,但C++允许在两者中使用它们。两种语言中的属性都不能是虚拟/抽象的。

您可以发现接口和抽象类之间的明显区别。

界面

接口仅包含抽象方法。强制用户在实现接口时实现所有方法。仅包含最终变量和静态变量。使用interface关键字声明。接口的所有方法都必须定义为public。一个接口可以扩展,或者一个类可以实现多个其他接口。

抽象类

抽象类包含抽象和非抽象方法。继承时不强制用户实现所有方法抽象类。包含所有类型的变量,包括基元和非基元使用abstract关键字声明。抽象类的方法和成员可以使用任何可见度子类只能扩展单个类(抽象或具体)。