java - 使方法实现的返回类型比抽象方法更具体

标签 java abstract-class

考虑这个抽象类

abstract class AbstractBox {
  abstract Object getContent();
}

现在我实现了一个 StringBox,但可能还有其他 Boxes 实现会返回任何类型的内容,阻止我将抽象的返回类型方法更具体:

class StringBox extends AbstractBox {
  @Override
  Object getContent() {
    return "";
  }
}

与其让 getContent() 声明它将返回一个 Object ,而且很明显它将返回一个 String,我也可以这样做

class StringBox extends AbstractBox {
  @Override
  String getContent() {
    return "";
  }
}

从而清楚地说明 getContent() 将返回什么,并且仍然覆盖抽象方法。

  1. 有这个名字吗?
  2. 它有什么缺点吗?

最佳答案

重写允许指定协变返回类型,在这里您可以在 StringBox 子类中使用它。

此功能从 Java 1.5 开始可用。
来自JLS.Chapter 8. Classes (重点是我的):

8.4.5. Method Result

...

Return types may vary among methods that override each other if the return types are reference types. The notion of return-type-substitutability supports covariant returns, that is, the specialization of the return type to a subtype.

在实践中,如果您使用声明了 StringBox 的类型来操作变量,那么类的客户端返回一个更具体的类型会有好处,这是一件好事,因为它避免了向下转型。

例如:

StringBox box = new StringBox();
String boxContent = box.getContent();

但是,如果您使用 AbstractBox 声明类型操作变量,它在编译时或运行时不会有任何副作用,因为客户端仍期望有 Object作为返回类型:

AbstractBox box = new StringBox();
Object boxContent = box.getContent();

如果使客户端代码更清晰和更简单(因为没有任何转换),则应该使用协方差返回的一般方式。

关于java - 使方法实现的返回类型比抽象方法更具体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49671081/

相关文章:

java - 如何将类实例化为变量名?

java - 为什么 Java 不编译这段代码?

实例属性的 Python NotImplementedError

oop - 何时使用接口(interface)而不是抽象类,反之亦然?

java - 动态数组创建导致 ArrayIndexOutOfBoundsException 和 NullPointerException

java - 使用忽略大小写的属性查找元素

启动时的 Java Jtable 行颜色

java - 通用决策树算法代码实现

java - 为什么扩展抽象类的类中的方法即使没有被调用也会运行?

c# - 从 C# 中反射(reflect)的 OOP 角度来看,动态多态性、抽象类和接口(interface)之间有什么区别?