java - 接口(interface)的意图与具有抽象方法的抽象类有何不同?

标签 java interface abstract-class

解释/序言

在 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();
}

您可以有效地声明一个具有各种“默认行为”的类(m_id 的 getter 和 setter)以及强制此类由必须实现“缺失”(抽象)方法的子类,例如

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

甚至可能覆盖父类(super class)中的方法。

所以它似乎一个带有抽象方法的抽象类的行为就好像它是一个接口(interface),

public interface IMy {
  public void setSomething(Object o);
  public Object getSomething();
}

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

问题

几乎似乎在现有的interfaceabstract class-with-abstract-methods (ACWAM) 中毫无意义,因为它们看起来非常相似。

  1. ACWAM 看起来接口(interface) 非常相似!我想本质上的区别在于他们的意图
  2. 我了解接口(interface) 旨在提供一种方式,让图书馆用户可以在不依赖于图书馆实现的情况下与图书馆“交谈”。 interface 旨在“向公众展示一些东西”,而 ACWAM 旨在让图书馆开发人员“同意”,但“提供默认(可覆盖)行为的额外奖励?
  3. 同时使用 interface 和 ACWAM 是否有意义?

您能否提供一个或两个简单示例(指向另一个文档就可以)来说明这两个(即 interface 和 ACWAM)在意图(或“良好使用”)上的差异?

最佳答案

接口(interface)和抽象类的最大区别是:

  • 抽象类将"is"关系强加给实现。您必须子类化抽象类。你永远被束缚在一个特定的类层次结构中
  • 接口(interface)对实现强加了一种“看起来像”的关系。只要它遵守接口(interface),你就可以继承任何你喜欢的东西。这使您可以自由地交换您喜欢的任何类(class)来完成这项工作。如果出现更好的情况,这将特别有用

一个好的工作规则是 API 应该始终引用接口(interface)。

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

然而,抽象类确实有其用武之地:它们可以提供接口(interface)的默认实现。一个很好的例子是 java.util.AbstractMap ,一个类,它是 java.util.Map 的骨架实现界面。

关于java - 接口(interface)的意图与具有抽象方法的抽象类有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7203887/

相关文章:

java - 在数组列表java中存储接口(interface)

java - 从 BMP 照片中提取内存初始化文件 (MIF)

Java - 在数据接收时向另一个线程触发事件

java - "Whiteout"整个 swing GUI 除了一个组件

强制实现枚举的 Java 接口(interface) - 如何处理?

Java RESTful Web 服务 - 注释接口(interface)而不是类

pointers - 为什么Go允许将接口(interface)变量分配给未实现值接收者的值?

c++ - 不同构造函数的命令行参数

c++ - 如何在链表中显示特定节点?

java - 抽象方法的 native 实现