【问题标题】:How can I override a method returning a List containing instances of subclass to the class the original methods List contained?如何覆盖将包含子类实例的列表返回到原始方法列表包含的类的方法?
【发布时间】:2020-05-30 11:57:00
【问题描述】:

我意识到标题有点乱,但这是我能想到的最好的了。

以下是我希望的一个最小示例,但目前未能做到。

public class ObjectA {}

public class ObjectB extends ObjectA {}

public interface HandlerInterface<T extends ObjectA> {

        public T easyToOverride();

        public List<T> hardToOverride();

}      

public class HandlerA implements HandlerInterface<ObjectA> {

        public ObjectA easyToOverride() {
                return new ObjectA();
        }

        public List<ObjectA> hardToOverride() {
                return new ArrayList<ObjectA>();
        }
}      

public class HandlerB extends HandlerA implements HandlerInterface<ObjectB> {

        /*
          This method ovverides its super method with ease since its return
          type directly inherits from the super class's return type
        */
        public ObjectB easyToOverride() {
                return new ObjectB();
        }

        /*
          This method is NOT accepted by the Java syntax since List<ObjectB>
          does NOT directly inherit from List<ObjectA>

          The method signature for hardToOverride() clashes with the signature
          in the super class and is not overridden because the return types
          don't obviously inherit each other
        */
         public List<ObjectB> hardToOverride() {
                return new ArrayList<ObjectB>();
        }
} 

忽略这些类应该在它们自己的文件中,并且我没有包含它们的导入。我这样写是为了方便阅读。

正如您可能已经通过 HandlerB 类中的 cmets 了解,方法 hardToOverride() 不被接受(将此代码放入您的 IDE 并观看它的尖叫声)。

我意识到我可以只返回一个 List&lt;Object&gt; 并将返回的 List 对象的内容类型转换为我个人知道的特定处理程序实例返回的类型(ObjectAObjectB),但这会这意味着任何使用这些方法的人都必须了解它们的内部工作原理,我不喜欢那样。

我想要的是能够用方法List&lt;ObjectB&gt; hardToOverride() 覆盖List&lt;ObjectA&gt; hardToOverride() 方法,而不会丢失这些方法提供的硬输入。

所以我的最后一个问题是:

有什么方法可以保留所有这些接口、继承和覆盖,而不会丢失它们在我的示例代码中提供的强类型?

如果不是,有什么更好的方法来实现一组实际有效的类似类和接口?

【问题讨论】:

  • 你可以创建一个接口,CommonInterface,把ObjectA和ObjectB中的所有常用方法,然后在父子上重写方法返回List。如果您需要使用 ObjectA 独有的方法,则首先检查对象是否为 ObjectA 的 instanceof,然后将其强制转换为使用 ObjectA 类中的方法。

标签: java inheritance interface overriding


【解决方案1】:

如果您使用新的泛型声明 HandlerA,即使它从未真正使用过,您的代码也会被接受:

public class HandlerA<T> implements HandlerInterface<ObjectA> {
//....
}

注意:这只是一种解决方法,但因此您的示例代码将按照您的要求运行。此外,即使 HandlerA 声明了一个泛型,你也可以在任何情况下实例化它而不用括号:

ObjectA objectA = new HandlerA();

【讨论】:

  • 这是否意味着我们可以使用任何非抽象类来实例化 HandlerA,因为 HandlerA 仍然是一个模板类(因为 )?我的问题的重点是尽可能多地消除歧义,并在保持我试图描述的特征的同时使打字尽可能强。
  • 是的。您还可以在泛型上使用 extends 语法来限制可用类,但这并不能消除歧义,除非您确实需要 HandlerA 上的新泛型。正如我所说,这只是一种解决方法,可让您准确使用您共享的代码。缺点是为编码器引入了低歧义性,但您可以通过专门记录类来解决这个问题。
猜你喜欢
  • 2011-05-13
  • 2019-04-21
  • 1970-01-01
  • 2019-10-25
  • 2022-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多