I have an interface like this:
public interface IEventListener
{
public <T extends MyCustomObject> void onEvent(final T object);
public <T extends MyCustomObject> void onEventTest2(final T object);
}
and in some other class that implements this interface i want call the same method but define whatever parameter i want like:
public class MyClass implements IEventListener
{
#Override
public <T> void onEvent(final Player player)
{
// My code here
}
#Override
public <T> void onEventTest2(final Item item)
{
// My code here
}
}
How can i achieve this ?
It seems very clear, now, that your generics should be on the type, not the method -- and with your edit, you'll just need multiple parameters, i.e.
interface IEventListener<T1 extends MyCustomObject, T2 extends MyCustomObject> {
void onEvent(T1 object);
void onEventTest2(T2 object);
}
public class MyClass implements IEventListener<Player, Item> {
#Override public void onEvent(Player player) { ... }
#Override public void onEventTest2(Item item) { ... }
}
There is not going to be any way you can have the generics on the methods; they must be on the type.
Related
I have an interface called A:
public interface A {
void X(T t);
}
I then have two subclasses (B and C) that implement this interface, but each of them pass a different type to X lets say B passes type foo and C passes type bar:
public class B implements A {
#Override
public <T extends foo> void X(T type1)
}
public class C implements A {
#Override
public <T extends bar> void X(T type2)
}
What am I doing wrong and why doesn't this work? The compiler keeps telling me that "Method does not override method from its superclass".
Thanks in advance!
Even with generic methods, when they are overridden, the generics must match exactly.
One way that might not meet your requirements is to remove the upper bounds on the implementing class, e.g.
class B implements A {
#Override
<T> void X(T type1) { /* impl */ }
}
But if you need the upper bound, then represent the upper bound with a type parameter on the interface.
interface A<U> {
<T extends U> void X(T t);
}
Then you can supply the type argument for the upper bound in the implementing classes.
class B implements A<Foo> {
#Override
public <T extends Foo> void X(T type1) { /* impl */ }
}
class C implements A<Bar> {
#Override
public <T extends Bar> void X(T type2) { /* impl */ }
}
But because anything you can call on T you can also call on Foo or Bar, maybe the methods don't need to be generic.
interface A<T> {
void X(T t);
}
class B implements A<Foo> {
#Override
public void X(Foo type1) { /* impl */ }
}
class C implements A<Bar> {
#Override
public void X(Bar type2) { /* impl */ }
}
I'm trying to override the following methods but I can't figure out the generics mechanism:
public interface MyInterface<T extends MyGenericObject> {
public void read(long id, Callback<T> callback);
public void readAll(Callback<Collection<T>> callback);
}
public class SomeObject extends MyGenericObject {
...
}
public class MyClass implements MyInterface<SomeObject> {
#Override
public void read(long id, **????** callback) {
...
}
#Override
public void readAll(**????** callback) {
...
}
}
Could you please help me?
EDIT: I had an intermediate Interface between MyClass and MyInterface and the generic SomeObject wasnt passed all the way, that was my problem...
Just replace each T by SomeObject which is passed to MyInterface<T>.
// T has become SomeObject = put everywhere SomeObject instead of T
public class MyClass implements MyInterface<SomeObject> {
#Override
public void read(long id, Callback<SomeObject> callback) {
...
}
#Override
public void readAll(Callback<Collection<SomeObject>> callback) {
...
}
}
EDIT
You have mentioned in comment that it does not compile due of erasure problem (why you getting this error is explained in comment section), however this is not possible with code you have posted:
public interface MyInterface<T extends MyGenericObject> {
void read(long id, Callback<T> callback);
void readAll(Callback<Collection<T>> callback);
}
public interface Callback<T> {}
public class MyGenericObject {}
public class SomeObject extends MyGenericObject {}
public class MyClass implements MyInterface<SomeObject> {
#Override public void read(long id, Callback<SomeObject> callback) {}
#Override public void readAll(Callback<Collection<SomeObject>> callback) {}
}
This code compiles without any error:
import java.util.Collection;
interface Callback<T> {}
class MyGenericObject {}
interface MyInterface<T extends MyGenericObject> {
public void read(long id, Callback<T> callback);
public void readAll(Callback<Collection<T>> callback);
}
class SomeObject extends MyGenericObject { }
class MyClass implements MyInterface<SomeObject> {
#Override
public void read(long id, Callback<SomeObject> callback) {
}
#Override
public void readAll(Callback<Collection<SomeObject>> callback) {
}
}
If you are getting "read/readAll in MyClass clashes with read/readAll in MyInterface; both methods have same erasure, yet neither overrides the other", then your code is different to what you have indicated.
Pretty sure you can just use Callback<SomeObject> callback and Callback<Collection<SomeObject>> callback respectively.
Try
public class MyClass<T extends SomeObject> implements MyInterface<T> {
Now you can use T in your method implementations. You will specify the specific class when you instantiate MyClass.
Let's say I have a generic builder type:
public abstract class Builder<T> {
public abstract T build();
}
Then a Foo class and a builder for it, which extends Builder:
public class Foo {
// stuff
}
public class FooBuilder extends Builder<Foo> {
public Foo build() {
return new Foo();
}
}
I also have an abstract, generic Handler type:
public abstract class Handler<T> {
public abstract <U extends Builder<T>> void handle(U builder);
}
and finally a FooHandler:
public class FooHandler extends Handler<Foo> {
#Override
public void handle(FooBuilder builder) {
// do something
}
}
The issue is that FooHandler's handle() is not recognized as overriding Handler's handle(): Method does not override method from its superclass. Is it possible to do this?
Move the type parameter to the class level
abstract class Handler<T, U extends Builder<T>> {
public abstract void handle(U builder);
}
class FooHandler extends Handler<Foo, FooBuilder> {
#Override
public void handle(FooBuilder builder) {
// do something
}
}
Problem:
I have two interfaces (here GenCarry and Gen):
public interface GenCarry<T extends Gen> {
GenCarry<T> setGen(T gen);
}
public interface Gen<T extends GenCarry> {
void applyOn(T carry);
}
It works when I ignore the 'rawtypes' Warning, but trying to complete them I don't get too far:
GenCarry<T extends Gen<GenCarry<T>>>
Gen<C extends GenCarry<Gen<C>>> -> error: not a valid substitute for the bounded parameter.
Question:
How would an interface like that look if complete - or is that even possible?
Is there a better approach to "generalize" an interface like that?
You can define two type parameters:
public interface GenCarry<K extends GenCarry<K, T>, T extends Gen<T, K>> {
GenCarry<K, T> setGen(T gen);
}
public interface Gen<K extends Gen<K, T>, T extends GenCarry<T, K>> {
void applyOn(T carry);
}
class StringGenCarry implements GenCarry<StringGenCarry, StringGen> {
#Override
public StringGenCarry setGen(StringGen client) {
...
}
}
class StringGen implements Gen<StringGen, StringGenCarry> {
#Override
public void applyOn(StringGenCarry network) {
...
}
}
Generic method :
public <T> void foo(T t);
Desired overridden method :
public void foo(MyType t);
What is the java syntax to achieve this?
A better design is.
interface Generic<T> {
void foo(T t);
}
class Impl implements Generic<MyType> {
#Override
public void foo(MyType t) { }
}
You might want to do something like this :
abstract class Parent {
public abstract <T extends Object> void foo(T t);
}
public class Implementor extends Parent {
#Override
public <MyType> void foo(MyType t) {
}
}
A similar question was answered here as well : Java generic method inheritance and override rules
interface Base {
public <T> void foo(T t);
}
class Derived implements Base {
public <T> void foo(T t){
}
}