【问题标题】:Covariance in inheritance继承中的协变
【发布时间】:2017-03-17 07:30:26
【问题描述】:

我有一个超类 SheetBuilder 和许多继承这个类的子类。 超类有一个所有类都继承的抽象方法。

protected abstract void printResults(String abc);

现在我想用不同的参数重载相同的方法,但我只需要为一个子类执行此操作。所以我改变了抽象方法如下,

protected abstract void printResults(Object abc);

这样我就可以用我想要接收的任何对象类型来实现我的子类,

子类实现:

protected void printResults(int abc) {
//
}

这是正确的标准还是有其他方法可以实现这一点?

【问题讨论】:

  • 你的方法应该尽可能的具体,子类真的用任何类型的对象打印结果吗?
  • 如果您创建了子类的实例,但将其称为超类的实例,然后调用foo.printResults(new Object()),您会发生什么?那显然不能调用printResults(int)方法...
  • ΦXocę 웃 Пepeúpa ツ :是的。我需要将不同类型的对象传递给每个子类。
  • Jon Skeet : foo.printResults(new Object()) 这永远不会发生,因为它被硬编码为 String 或 int。
  • int 甚至不是对象引用,而是原语,因此将父抽象方法参数声明为 Object 没有任何好处。即使 printResult(int) 和 printResult(X) (其中 X 是任何类)共享名称,它们实际上也是两个不同/独立的方法;当然,它们应该共享语义,因为它们共享相同的名称……这就是重载的“灵魂”。

标签: java generics inheritance covariance


【解决方案1】:
protected abstract void printResults(Object abc);

现在我想用不同的参数重载相同的方法,但是 我只需要为一个子类执行此操作。所以我改变了摘要 方法如下, 这是正确的标准还是有其他方法可以实现 这个?

不,对象太宽。从客户端,如果您想通过接口编程,您必须调用此printResults(Object abc);
您可以将任何类型的实例放入其中。

此外,我认为您将覆盖和重载混合在一起。这是重载而不是覆盖,因为覆盖不能更改声明的参数类型:

class Base{ 
  protected abstract void printResults(Object abc);
}
...  
class BaseImpl{
  protected void printResults(String abc) {
    ...
  }
}

这里BaseImpl有两个方法printResults()。

如果在BaseImpl方法中添加@Override,编译会失败,因为不是同一个方法:

class Base{ 
  protected abstract void printResults(Object abc);
}
...  
class BaseImpl{
@Override
  protected void printResults(String abc) {
    ...
  }
}

要回答您的问题,如果 void printResults(String abc) 特定于单个类,请仅在该类中添加此方法。
在这种情况下,您不能通过接口编程来调用此方法,因为此方法特定于一个类。
但如果方法是特定的,它是可以接受的,有时甚至是可取的。

解决您的问题的另一种方法是使用泛型方法创建一个基类,根据具体类,参数可能具有不同的类型,请使用泛型:

class Base <T>{ 
  protected abstract void printResults(T abc);
}
...  

class BaseStringImpl<String>{
@Override
  protected void printResults(String abc) {
   ...
  }
}

...
class BaseIntegerImpl<Integer>{
@Override
  protected void printResults(Integer abc) {
   ...
  }
}

【讨论】:

  • “此外,我认为您将覆盖和重载混合在一起。” - 我从来没有在我的问题中提到过覆盖:)
  • @mani_nz 我知道,但你写的代码看起来像是覆盖 :)
  • 感谢 Davidxxx!这帮助我探索了更多选择 :) 干杯!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多