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 */ }
}
Related
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.
Using a library with an abstract class A and interfaces I and J, I get the following warning message when I extend / implement the class / interfaces:
Missing type arguments for generic class J<T>.
As a MWE, the classes are as follows (T and S are generic type parameters):
public abstract class A {}
public interface I<T extends A> {
public <S extends T> void doStuff(J<? super S> param);
}
public interface J<T extends A> {
public void doOtherStuff();
}
Here are my classes:
public class AExtended extends A {}
public class IImplemented implements I<AExtended> {
#Override
public void doStuff(J param) {}
}
Explicitly using the class AExtended as below does not properly implement doStuff() from I:
public class IImplemented implements I<AExtended> {
#Override
public void doStuff(J<AExtended> param) {}
}
You're not overriding doStuff in IImplemented because the method is not generic and the type bounds are not present. This version of doStuff should work for you:
public <S extends AExtended> void doStuff(J<? super S> param) {}
Notice that since the type of I is AExtended it is used appropriately here, and the lower bound in the wildcard type for J is also included.
try with:
public class IImplemented implements I<AExtended> {
#Override
public <S extends AExtended> void doStuff(J<? super S> param) {
// ...
}
}
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){
}
}
Suppose I have the following static method and interface (List is java.util.List). Note that the static method enforces a "super Foo" on the wildcard type of the list.
public class StaticMethod {
public static void doSomething(List<? super Foo> fooList) {
...
}
}
public interface MyInterface<T> {
public void aMethod(List<T> aList);
}
I would like to be able to add a class which implements the interface using the static method as follows:
public class MyClass<T> implements MyInterface<T> {
public void aMethod(List<T> aList) {
StaticMethod.doSomething(aList);
}
}
This obviously won't compile because T does not have the "super Foo" constraint. However, I can't see any way of adding the "super Foo" constraint. For example - the following is not legal:
public class MyClass<T super Foo> implements MyInterface<T> {
public void aMethod(List<T> aList) {
StaticMethod.doSomething(aList);
}
}
Is there any way of solving this problem - ideally without altering StaticMethod or MyInterface?
I'm going out on a limb here, but I think lower bounding is the problem here, because you have to know about the actual class that fits the bound when you refer to it... you can't use inheritance.
Here's a usage that compiles, but notice that I need to name the actual class that is a super of Foo:
class SomeOtherClass
{
}
class Foo extends SomeOtherClass
{
}
class StaticMethod
{
public static <T> void doSomething(List<? super Foo> fooList)
{
}
}
interface MyInterface<T>
{
public void aMethod(List<T> aList);
}
class MySpecificClass implements MyInterface<SomeOtherClass>
{
public void aMethod(List<SomeOtherClass> aList)
{
StaticMethod.doSomething(aList);
}
}
Comments?
p.s. I like the question :)
If you are sure that aList contains objects that can be safely cast to <? super Foo>, then you can do:
public static class MyClass<T> implements MyInterface<T> {
#Override
public void aMethod(List<T> aList) {
StaticMethod.doSomething((List<? super Foo>) aList);
}
}
See the complete and working example: http://ideone.com/fvm67