2012-11-20 31 views
4

我在我的Java代码中遇到了问题。我有四个(重要)类:如何使用子类型? - 覆盖并继承在Java中

public class RDOutput extends OutputType 
public class RDAnalysis extends AnalysisProperties 

现在我试图在分析性能的方法:

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

的主要问题清单,在ArrayList中的对象将是不同的亚型输出类型。在我的课堂RDAnalysis我尽量让特定压倒一切:

public void display(ArrayList<RDOutput> results) { 

但是Eclipse说:名称冲突:类型RDAnalysis的方法显示(ArrayList中)具有相同的擦除的显示(?ArrayList的扩展输出类型)类型AnalysisProperties,但不覆盖它

我不熟悉Java的技巧,我试图在文档中搜索,我没有找到任何解决这个问题的方法。 我的问题是:我在做Java(如果可以,我怎么能做到这一点?)或者我必须做一些枚举来解决这个问题(我在做抽象和扩展的基本类型)

+1

您可能还会看看“Java泛型:什么是PECS?”http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs – Greg

回答

3

我建议你到泛型参数介绍给你的类并用它来参数化你的方法:

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) {}  
} 
+0

爱你。谢谢。 –

0

如果一个方法需要ArrayList<? extends OutputType>

ArrayList<RDOutput>不能被传递给它,因为父类型允许ArrayList中的任何子类的OutputType。

考虑这样

AnalysisProperties properties = new RDAnalysis(); 
properties.display(arraylist consisting of any child class of OutputType); //this line will  cause runtime problems 
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) { 
    } 
} 
0

问题是,你试图重写一个方法,同时限制可能的参数。

=>ArrayList<? extends OutputType>接受比ArrayList<RDOutput>更多的可能元素,因为RDOutput延伸OutputType

你打破了这样的规则:有关的子类方法必须至少包含超类的元素,并且从不限制它们。

因此,编译器避免了有效的覆盖。

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

0

问题在于,在type erasure发挥作用后,两种方法的签名是不可区分的:它们具有相同的返回类型,它们都可以接受ArrayList<RDOutput>,但第一个(通用的)方法也可以接受任何ArrayList<T extends OutputType>

这意味着,虽然如果您通过ArrayList<RDOutput>,JVM将无法选择在运行时调用哪一个,同时您的display方法不会覆盖抽象的方法,因为您的方法仅适用于列表RDOutput,所以如果您通过List<T extends OutputType>T != RDOutput您的具体实施不接受它。

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