Implement an abstract generic method in Java with several types of generics

I will ask a very short question and hope that someone can help me with the solution. It describes generic methods in Java with two types of generics (one for the return type and the other for the formal parameter) and how to implement it. I guess I am missing something in the picture to make it work.

The fact is that...

This works :

public enum Getter { BillItemsSize { @Override public Integer get (Object entity) { DesiredClass ref = (DesiredClass ) entity; // "Old time" cast // do things... } }; public abstract <T,K> T get (K entity); } 

This does not work :

 public enum Getter { BillItemsSize { @Override public Integer get (DesiredClass entity) { // no cast at all // do things } }; public abstract <T,K> T get (K entity); } 

The java compiler yells to me:

 <anonymous datasource.db.Getter$1> is not abstract and does not override abstract method <T,K>get(K) in Getter 

Good thing the situation is. Thanks in advance to everyone !. Hope this helps others in the future!

PD: This is not an enumeration type problem .. it happens across class hierarchies. So don’t worry blaming emuns ... I have tried this and it doesn’t work either.

 public abstract class SuperClass { public abstract <T,E> T pepe (E e); } public class SubClass extends SuperClass { @Override public Integer pepe(DesiredClass e) // fails... { return null; } } 

UPDATED:

For Generics Options

We can make a rule of the general rule that for a “generics parameter” (those whose types are common), a type implicitly accepted in the method signature is equal to the upper limits of this general, which can be Object, if nothing is specified, or a more specific subclass, if upper bounds are used (in the example T extends String).

For Generics returns types

There is no problem rewriting a generic method with a specific return type, since the return type is a subtype of the rewritable return type. And what is the return type in the first place? Well, it turns out to be an object. By default, the compiler assumes (in the method signature) a generic type as an object type.

So, we have to say that the trick is to know that any method that has a common return type is actually an Object return type. Then, if the method is overwritten in any subclasses, and we change its return type, indicating that we return another type, there will be no problems. Because, besides the fact that this method will return an object of another class, this return object will inevitably be a subclass of the Object class, and the problem will not be overwritten with another type of return type, which the original must be a subtype of the original, A method called covariant return type allows us to do such a thing.

 public abstract class SuperClass { public abstract <T> T operation (); } public class SubClass extends SuperClass { @Override public Chair operation() { //bla bla } } 

meanwhile in another piece of code ...

 void main () { SubClass sb = new SubClass(); Chair chair = sb.operation (); // the chair type can be easely replaced by super type (like Object) Object object = sb.operation(); } 

Thanks to everyone who helps to understand this!

+7
source share
2 answers
 public abstract <T,K> T get (K entity); 

is a method that can take something as an argument and is allowed to return something.

Override with

 public Integer get (DesiredClass entity) 

does not work, because you limit the types of arguments that can be passed to the DesiredClass method, and thus violate the Liskov principle.

It would be easier to understand without generics. Suppose you have an abstract method in the Bar class:

 public abstract void fillRecipient(Recipient r); 

and you are trying to override it in SubBar with

 public void fillRecipient(Glass glass) { } 

What would the following code do if the above were legal?

 Bar bar = new SubBar(); bar.fillRecipient(new Mug()); 
+10
source

To complete up to JB Nizet answer when you write:

<K>

This implicitly means:

<K extends Object>

This method should accept any object. The restriction to DesiredClass in a subclass does not actually overwrite anything, as the error message says.

overridden methods must have exactly the same signature; no sub / super types are allowed in either parameters or return types.

Edit: Actually, as discussed in the comments, String public foo(); effectively cancels Object public foo(); .

+4
source

All Articles