接口的意图与使用抽象方法的抽象类有何不同?

jba*_*sta 3 java abstract-class interface

解释/序言

在Java中,如果使用抽象方法声明抽象类,例如

public abstract class MyAbstractClass {
  private String m_id;

  // default behavior
  public MyAbstractClass() { setId(null); }
  public String getId() { return m_id; }
  public void setId(String id) { m_id = id; }

  // overridenable method
  public void doSomething() { /* does nothing by default */ }

  // to-be-defined behavior
  public abstract void setSomething(Object o);
  public abstract Object getSomething();
}
Run Code Online (Sandbox Code Playgroud)

可以有效地宣告它有各种各样的"默认行为"(getter和setter的一类m_id),以及迫使这个类是由一个子类实例化具有实施"失踪"(抽象)方法,例如

public class MyClass extends MyAbstractClass {
  private Object m_o;

  // implements some actual complex behavior
  public void setSomething(Object o) { m_o = o; }
  public Object getSomething() { return m_o; }
}
Run Code Online (Sandbox Code Playgroud)

甚至可能覆盖超类中的方法.

所以看起来抽象方法的抽象类表现得像是一个interface,

public interface IMy {
  public void setSomething(Object o);
  public Object getSomething();
}
Run Code Online (Sandbox Code Playgroud)

因为要使用它,它必须最终指向一个实际的对象.

问题

几乎看起来好像在现有的两个interfaceabstract class--with-abstract-methods(ACWAM)中都没有意义,因为它们看起来非常相似.

  1. 该ACWAM似乎难以置信的相似interface!我认为根本区别在于他们的意图.
  2. 我理解,interface打算提供一种方法,库用户可以与库"交谈",而不依赖于库的实现.这是一个正确的解释,一个interface旨在"向公众展示一些东西",而ACWAM是一个旨在让图书馆开发人员"同意",但提供默认的"额外奖励"(可覆盖的行为?
  3. 难道是有意义的使用interface,同时作为ACWAM?

你能提供一两个简单的例子(指向另一个文件会很好)来说明这两个人的意图(或"好用")的差异,即interfaceACWAM?

Boh*_*ian 5

接口和抽象类之间的最大区别是:

  • 抽象类强制实现"是一种"关系.您必须子类化抽象类.您永远被绑定到特定的类层次结构中
  • 接口强制实现"看起来像"关系.只要它遵循接口,您就可以将任何您喜欢的子类化.这使您可以在任何您喜欢的课程中进行交换.如果出现更好的一个,这尤其有用

一个好的规则就是API应该始终引用接口.

请注意,JDK中充斥着早期在使用接口应该使用的(抽象)类的错误.Stack就是一个很好的例子:Stack 应该是一个接口,但它是一个类.如果你想实现自己的堆栈,你必须继承 java.util.Stack,这是非常规范的 - 你可能不想这样做 - 也许你需要一个超轻量级版本等.

然而,抽象类确实有它们的位置:它们可以提供接口的默认实现.一个很好的例子是java.util.AbstractMap,这是一个java.util.Map接口的骨干实现的类.

  • +1,还值得一提的是你不能从`Java`中的多个类继承.因此,抽象类而不是接口的误用可能导致没有"扩展"可能. (2认同)