4

I've got problem in my code in Java. I have four(important) Classes:

public class RDOutput extends OutputType
public class RDAnalysis extends AnalysisProperties 

Now I'm trying to make a method in Analysis properties:

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

The main problem list, the objects in the ArrayList will be different subtypes of OutputType. In my class RDAnalysis I try to make specific overriding:

public void display(ArrayList<RDOutput> results) {

but eclipse says: Name clash: The method display(ArrayList) of type RDAnalysis has the same erasure as display(ArrayList? extends OutputType) of type AnalysisProperties but does not override it

I'm not familiar with Java tricks, I tried searching in documentation and I didn't find any solution to this problem. My question is: Is that trick that I'm doing (Basic type in abstract and Extended in final function) possible in Java (if yes, how can I do that?) or do I have to make some enum to solve this?

  • 1
    You might also check out "Java Generics: What is PECS? "http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs – Greg Nov 20 '12 at 20:44

5 Answers5

3

I suggest you to introduce generic parameter to your class and use it to parametrize your method:

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) {}     
}
hoaz
  • 9,883
  • 4
  • 42
  • 53
2

It's because your display doesn't cover every case of the abstract method. Maybe try something like this :

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) {
    }
}
Javadrien
  • 201
  • 1
  • 6
0

if a method is expecting ArrayList<? extends OutputType>

ArrayList<RDOutput> cannot be passed to it, as parent type allows any child class of OutputType in arraylist.

consider a code like this

AnalysisProperties properties = new RDAnalysis();
properties.display(arraylist consisting of any child class of OutputType); //this line will        cause runtime problems
Subin Sebastian
  • 10,870
  • 3
  • 37
  • 42
0

The problem is that you try to override a method while restricting possible parameters.

=> ArrayList<? extends OutputType> accepts more possible elements than ArrayList<RDOutput> since RDOutput extends OutputType.

You break the rule that says: the concerned subclass method has to encompass at least elements of superclass one and NEVER restrict them.

So compiler avoid to valid this override.

By the way, avoid to type your reference with concrete values like ArrayList. What about a LinkedList passed as arguments? ... prefer a more generic relevant type like List.

Mik378
  • 21,881
  • 15
  • 82
  • 180
0

Problem here is that, after type erasure comes into play, the signature of the two methods are undistinguishable: they have the same return type and they can both accept a ArrayList<RDOutput> but the first one (the generic one) can also accept any ArrayList<T extends OutputType>.

This mean that, although the JVM won't be able to choose which one to call at runtime if you pass an ArrayList<RDOutput>, at the same time your display method does not override the abstract one because your method only work for lists of RDOutput, so if you pass a List<T extends OutputType> with T != RDOutput your specific implementation doesn't accept it.

You should consider using a type parameter on the whole class as suggested in other answers, or accept the fact that you won't be able to use any RDOutput specific methods in your display method without a cast.

Jack
  • 131,802
  • 30
  • 241
  • 343