Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding generic methods with non-generic implementations

Tags:

java

generics

I'm experimenting with generics in Java, and thought of this example.

If I have ClassA<T>, I can override it with a subclass that references a concrete class, such as ClassB extends ClassA<String>, then anywhere ClassA uses T, ClassB can use a String.

Now, ignoring the previous ClassA and ClassB, if I have an abstract ClassA, which has a generic method:

public <T> void doSomething(T data);

Is there any way I can have a ClassB that overrides it with a concrete class, similar to the previous example? I've come up with something that works, which is to parameterize both the class and the method, but I'm wondering if there's another way.

class ClassA<T> {
    public void doSomething(T data) {};
}

The reason I don't want to put the parameter in the class is because it's only one method that does anything with that type, and some subclasses may not even want to do anything in that method, so I shouldn't need to put a parameter in the class if it's not going to use it.

NOTE: All of the subclasses of ClassA are anonymous classes, so that adds to the fun.

like image 863
Ed Marty Avatar asked Mar 01 '10 17:03

Ed Marty


People also ask

Can you have a generic method in a non-generic class?

Generic methods in non-generic classYes, you can define a generic method in a non-generic class in Java.

Can we have generic method in non-generic class in C#?

Yes, There are two level where you can apply generic type . You can apply generic type on Method level as well as Class level (both are optional).

Can I use polymorphism in generics?

The polymorphism applies only to the 'base' type (type of the collection class) and NOT to the generics type.

Can a generic class be a subclass of a non-generic class?

A generic class can extend a non-generic class.


2 Answers

Thanks to type erasure, this:

public <T> void doSomething(T data);

Really means this:

public void doSomething(Object data);

So no, there isn't a way to override with a more restrictive parameter type.

Also in this code:

class ClassA<T> {
    public <T> void doSomething(T data) {};
}

The type parameter in your class name and the type parameter in the method are actually different parameters. It's like declaring a local variable of the same name as a variable in a higher scope. You can call doSomething(123) on an instance of ClassA<String> because the second T is local to the method.

like image 126
noah Avatar answered Nov 06 '22 20:11

noah


In short, the the answer is no. If you define a method with a generic parameter, then its signature contains a the generic and any "overrides" would have to match the signature (contain a generic).

Anyhow, this really is a poor use of generics, as what you've written is semantically the same as

public void doSomething(Object data) {}

The generic bit doesn't buy you much unless is it being used to indicate what the return value would be, as in:

public <T> T doSomething(T data) {}

But why bother? Is there really an issue calling doSomething() generically?

like image 28
Matthew Flynn Avatar answered Nov 06 '22 18:11

Matthew Flynn