【问题标题】:How to use subtypes? - overriding and inheriting in Java如何使用子类型? - Java 中的覆盖和继承
【发布时间】:2012-11-20 20:28:46
【问题描述】:

我的 Java 代码有问题。我有四个(重要的)课程:

public class RDOutput extends OutputType
public class RDAnalysis extends AnalysisProperties 

现在我正在尝试在分析属性中创建一个方法:

public abstract void display(ArrayList<? extends OutputType> results);

主要问题列表,ArrayList中的对象会是OutputType的不同子类型。在我的课程 RDAnalysis 中,我尝试进行特定的覆盖:

public void display(ArrayList<RDOutput> results) {

但 eclipse 说:名称冲突:RDAnalysis 类型的方法 display(ArrayList) 与 AnalysisProperties 类型的 display(ArrayList? extends OutputType) 具有相同的擦除,但不会覆盖它

我不熟悉 Java 技巧,我尝试在文档中搜索,但没有找到任何解决此问题的方法。 我的问题是:我正在做的那个技巧(抽象的基本类型和最终函数中的扩展)在 Java 中是否可行(如果是,我该怎么做?)还是我必须做一些枚举来解决这个问题?

【问题讨论】:

标签: java inheritance overriding wildcard


【解决方案1】:

我建议你在你的类中引入泛型参数并用它来参数化你的方法:

public abstract class A<T extends OutputType> {
    public abstract void display(ArrayList<T> results);     
}

public class B extends A<RDOutput> {
    public void display(ArrayList<RDOutput> results) {}     
}

【讨论】:

    【解决方案2】:

    这是因为您的显示并未涵盖抽象方法的所有情况。也许尝试这样的事情:

    public class RDOutput extends OutputType {}
    
    public class OutputType {}
    
    public abstract class AnalysisProperties<T extends OutputType> {
        public abstract void display(ArrayList<T> results);
    }
    
    public class RDAnalysis extends AnalysisProperties<RDOutput> {
        @Override
        public void display(final ArrayList<RDOutput> results) {
        }
    }
    

    【讨论】:

      【解决方案3】:

      问题是你试图在限制可能的参数的同时覆盖一个方法。

      => ArrayList&lt;? extends OutputType&gt; 接受比 ArrayList&lt;RDOutput&gt; 更多的可能元素,因为 RDOutput 扩展了 OutputType

      您违反了以下规则:相关子类方法必须至少包含超类 1 的元素,并且永远不要限制它们。

      所以编译器避免验证这个覆盖。

      顺便说一句,请避免使用ArrayList 等具体值键入您的引用。 作为参数传递的LinkedList 怎么样? ... 更喜欢更通用的相关类型,例如 List

      【讨论】:

        【解决方案4】:

        这里的问题是,在type erasure 起作用后,这两个方法的签名无法区分:它们具有相同的返回类型,并且都可以接受ArrayList&lt;RDOutput&gt;,但第一个(通用的)可以也接受任何ArrayList&lt;T extends OutputType&gt;

        这意味着,虽然 JVM 将无法选择在运行时调用哪一个,如果你传递一个 ArrayList&lt;RDOutput&gt;,同时你的 display 方法不会覆盖抽象的,因为你的方法只为RDOutput 列表工作,所以如果你通过List&lt;T extends OutputType&gt;T != RDOutput 你的具体实现不接受它。

        您应该考虑按照其他答案中的建议在整个类上使用类型参数,或者接受这样一个事实,即如果没有强制转换,您将无法在 display 方法中使用任何 RDOutput 特定方法。

        【讨论】:

          【解决方案5】:

          如果一个方法期待ArrayList&lt;? extends OutputType&gt;

          ArrayList&lt;RDOutput&gt; 不能传递给它,因为父类型允许在 arraylist 中的任何子类 OutputType。

          考虑这样的代码

          AnalysisProperties properties = new RDAnalysis();
          properties.display(arraylist consisting of any child class of OutputType); //this line will        cause runtime problems
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-08-22
            • 1970-01-01
            • 2013-03-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-08-13
            相关资源
            最近更新 更多