How to use subtypes? - redefinition and inheritance of Java

I have a problem in my Java code. I have four (important) classes:

public class RDOutput extends OutputType public class RDAnalysis extends AnalysisProperties 

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

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

In the main list of problems, objects in ArrayList will be different subtypes of OutputType. In my RDAnalysis class, I am trying to do a specific override:

 public void display(ArrayList<RDOutput> results) { 

but eclipse says: name collision: mapping a method (ArrayList) of type RDAnalysis has the same erasure as mapping (ArrayList? extends OutputType) of type AnalysisProperties, but does not cancel it

I am not familiar with Java tricks, I tried to search the documentation and I did not find a solution to this problem. My question is: is this a trick I'm doing (base type in abstract and extended in final function) possible in Java (if so, how can I do this?) Or do I need to do some enumerations to solve this problem?

+4
source share
5 answers

I suggest you introduce a generic parameter in your class and use it to parameterize 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) {} } 
+3
source

This is because your display does not cover every case of an 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) { } } 
+2
source

if the expected method is ArrayList<? extends OutputType> ArrayList<? extends OutputType>

ArrayList<RDOutput> cannot be passed to it, since the parent type resolves any child class of OutputType to arraylist.

consider such a code

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

The problem is that you are trying to override the method, limiting the possible parameters.

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

You are breaking a rule that says: the appropriate subclass method should include at least the elements of the superclass one and NEVER limit them.

Therefore, the compiler avoids the validity of this override.

By the way, do not enter a link with specific values, for example ArrayList . What about LinkedList passed as arguments? ... prefer a more general type of relay like List .

0
source

The problem is that after the erasure type comes into play, the signature of the two methods is indistinguishable: they have the same return type and they can accept ArrayList<RDOutput> , but the first (common) can also accept any ArrayList<T extends OutputType> .

This means that although the JVM cannot choose which one to call at run time if you pass an ArrayList<RDOutput> , at the same time, your display method does not override the abstract, since only your method work on RDOutput lists, so if you pass List<T extends OutputType> with T != RDOutput , your particular implementation does not accept it.

You should consider using a type parameter for the entire class, as suggested in other answers, or accepting the fact that you cannot use any special RDOutput methods in your display method without translation.

0
source

Source: https://habr.com/ru/post/1447332/


All Articles