I have an interface A, and wish to write an generic interface B such that any T that implements B must also have implemented both A and Comparable. A is not currently a generic interface.
Is this possible? Do I need to make A generic?
I had hoped to be able to write something like:
public interface B<T implements Comparable, A> {}
But this does not seem to work... Can anyone point me in the right direction?
I do not believe this is a duplicate of the question that has been linked.
What you are looking for here are multi-bounded generic types:
public interface B<T extends A & Comparable> {}
Note that if either of the bounded types is a class instead of an interface, it has to be the first bound defined after extends. Also, you cannot use multi-bounded generic types on more than one class(since there is no multiple-inheritance in Java)
Just make B to extend A and Comparable.
public interface A {
public void methodA();
}
public interface B<T> extends A, Comparable<T> {
public T methodB();
}
public class BImpl<T> implements B<T> {
#Override
public T methodB() {
return null;
}
#Override
public void methodA() {
}
#Override
public int compareTo(T o) {
return 0;
}
}
Related
I would like to create an Java interface with a method that accepts all subtypes of a type:
interface A{};
interface B{
void method(A a);
}
What I want to accomplish is to make an implementation of the method(A a) accept
all subtypes of A (like return type polymorphism but with an argument).
Is this even possible?
You've already done it!
To prove it, try something like this:
public class ThisA implements A {}
public class ThatA implements A {}
public class OtherA implements A {}
public class SubclassA extends OtherA {}
then call your method:
B b = new B {
public void method(A a) {
System.out.println("Called with "+a);
}
}
b.method(new ThisA());
b.method(new ThatA());
b.method(new OtherA());
b.method(new SubclassA());
I had a question about similar generics yesterday, and as solution I implemented a sort of self-reference in some classes, like this:
public interface Action { }
public interface Result { }
public interface Player<A extends Action, R extends Result, P extends Player<A, R, P>> {
default public void onPostAction(final P target, final A action, final R result) { }
}
abstract public class GesturePlayer<A extends Action, R extends Result, P extends GesturePlayer<A, R, P>> implements Player<A, R, P> { }
abstract public class RPSPlayer extends GesturePlayer<RPSGesture, RPSResult, RPSPlayer> { }
public class RPSHumanPlayer extends RPSPlayer {
#Override
public void onPostAction(final RPSHumanPlayer target, final RPSGesture gesture, final RPSResult result) { }
}
This code does not compile, hoewver I am unable to figure out why.
It does work if in the #Override I use RPSPlayer, however RPSHumanPlayer is simply a subclass of it, should it not work the same as the following?
List<T> list = new ArrayList<>();
Which also has the type definied as the superclass (List resp RPSPlayer), and the referenced object's type as the subclass (ArrayLast resp RPSHumanPlayer).
My aim with this question is to gather insight on how the generics exactly work, and I want to keep the method signature as it is defined in RPSHumanPlayer.
What I think I understand about generics:
T is a typed parameter, like List<String>, etc. Also able to use it for own classes and methods. This also captures all subclasses of T.
? captures all possible Objects. Used to ensure that something is generic and not raw.
? extends T capture a specific subclass of T.
This code is written on Java 8.
In order to achieve the desired method signature in RPSHumanPlayer, you will need to generify RPSPlayer like this:
abstract public class RPSPlayer<P extends RPSPlayer<P>> extends GesturePlayer<RPSGesture, RPSResult, P> { }
Then you can define:
public class RPSHumanPlayer extends RPSPlayer<RPSHumanPlayer>
In Java, parameter types are part of the method signature, so they can't be changed (not even subclassed). Since Java 5, you can use covariant return types, but that's as far as it goes.
Your problem boils down to this:
public interface Player {
default public void onPostAction(Player target) {}
}
public abstract class HumanPlayer implements Player {
#Override
public void onPostAction(HumanPlayer target) {}
}
This cannot work, because onPostAction(HumanPlayer) cannot override onPostAction(Player), because then what would happen if it was called with a Player that was not a HumanPlayer?
I have some problems implementing a Java feature.
I have a list of Sensors. I have different kinds of them, they all extend the base class Sensor.
I have some abstract functions in the base class, and I want these functions to take an Enum as a parameter. The problem is that the Enum is unique for each sub class, and therefore, I can't declare the Enum in the base class.
The code below has Enum as parameter. I know it's not legal syntax, but I just want to illustrate that this is where I want to have the sub class Enum as parameter.
private Vector<Sensor> sensors;
public abstract class Sensor {
public Sensor() {}
public abstract int getParam(Enum param);
public abstract void setParam(Enum param, int value);
}
public class TempSensor extends Sensor {
// Parameter names
public static enum TEMP_PARAMETERS{ PARAM_ALARM_HI, PARAM_ALARM_LO }
public TempSensor() {}
#Override
public int getParam(TEMP_PARAMETERS param) {
// Will do some stuff here
return 0;
}
#Override
public void setParam(TEMP_PARAMETERS param, int value) {
// Will do some stuff here
}
}
If the different Enums implement an interface, I can use the interface as the parameter type in the abstract methods, but then I can pass Enums that don't belong to the respective class as parameter. Is there a way to avoid that?
Looks like you want contradictory things. The whole point of using polymorphism is to take advantage of the substitution principle.
If you want to have a class hierarchy and be sure the right type is entered to the right object, you may consider using the factory pattern.
I strongly recommend against inheritance on Enums; Java doesn't handle that well.
You're on the right track. Assuming you have a marker interface called MyEnumTypeInterface, just have your different enums implement that inferface. Then use MyEnumTypeInterface as the type of the formal parameter for your methods that accept the enum. However, you need to ensure that you're getting an enum that implements MyEnumTypeInterface and not just any other class that implements MyEnumTypeInterface:
public <E extends Enum<E> & MyEnumTypeInterface>void getParam(E e)
This ensures that the formal parameter is an enum and that it implements MyEnumTypeInterface; the methed won't accept as a parameter, another class that also implements MyEnumTypeInterface.
So your classes end up looking like this:
public interface MyEnumTypeInterface {
}
public abstract class Sensor {
public Sensor() {}
public abstract <E extends Enum<E> & MyEnumTypeInterface>int getParam(E param);
public abstract <E extends Enum<E> & MyEnumTypeInterface>void setParam(E param, int value);
}
public enum TempEnum extends MyEnumTypeInterface {
PARAM_ALARM_HI,
PARAM_ALARM_LO
}
public class TempSensor extends Sensor {
public TempSensor() {}
#Override
public<E extends Enum<E> & MyEnumTypeInterface>int getParam(E param) {
return 0;
}
#Override
public <E extends Enum<E> & MyEnumTypeInterface>void setParam(E param, int value) {
// Will do some stuff here
}
}
So you want each Sensor to work a particular param type? That would mean making Sensor generic.
public abstract class Sensor<P extend Enum<P>> {
public Sensor() {}
public abstract int getParam(P param);
public abstract void setParam(P param, int value);
}
There are probably bigger problems with you design. Fixing those could remove the requirement for the get and set.
Imagine we have following classes:
public interface MyInterface<T> {
List<T> getList(T t);
}
abstract class BaseClass<T extends Number> implements MyInterface<T> {
#Override
public List<T> getList(Number t) {
return null;
}
}
class ChildClass extends BaseClass<Integer> {
#Override
public List<Integer> getList(Integer t) {
return super.getList(t); //this doesn't compile
}
}
getList in ChildClass doesn't compile, the output is:
abstract method getList(T) in com.mypackage.MyInterface cannot be accessed directly
I can't get why BaseClass.getList method isn't overriden in ChildClass.
But what makes me completely confused is the fix that makes it compile:
class ChildClass extends BaseClass<Integer> {
#Override
public List<Integer> getList(Integer t) {
return super.getList((Number) t); //Now it compiles!
}
}
So I cast Integer to Number, and is solves the problem.
Could anyone explain what's going on in this code?
Your base class should look like:
abstract class BaseClass<T extends Number> implements MyInterface<T> {
#Override
public List<T> getList(T t) {
return null;
}
}
You weren't using T, but the Number class as a parameter.
It doesn't override because the abstract method takes a Number as a parameter and the concrete method takes an Integer. They must be the same in order to override.
You should change your abstract class implementation to take type T as a parameter.
Why isn't the superclass method defined as
public List<T> getList(T t)
?
What is going on in the imaginary class.
abstract class BaseClass<T extends Number> implements MyInterface<T> {
#Override
public List<T> getList(Number t) {
return null;
}
}
This class has one generic parameter (T) that has to extend Number class and implement the interface MyInterface
You also Try to override a method that does not exists, because this class do not extend other any class. While a class is implementing an interface there is no need to override the interface method because the are only the description.
What happen if we remove the #override annotation.
abstract class BaseClass<T extends Number> implements MyInterface<T> {
public List<T> getList(Number t) {
return null;
}
}
In this case we do not implement the method from the interface but create a new one, a this method parameter is Number that is same type as T, it will probably cause some error that class has two the same methods. (not tested by compiler)
Them implementation of this method should look like this
abstract class BaseClass<T extends Number> implements MyInterface<T> {
public List<T> getList(T t) { //Because T is allready restricted to be Number
return null;
}
}
And when You specify the type You will not have a problem to call this method when you override it
class ChildClass extends BaseClass<Integer> {
#Override
public List<Integer> getList(Integer t) {
return super.getList(t);
}
}
In advance You don have to implement it only for return null and then override it in some child class. What You can do is create class like this
abstract class BaseClass<T extends Number> implements MyInterface<T> {
private List<T> list = new ArrayList<T>(); //The way of initialization is up to You
public List<T> getList() { //Because T is allready restricted to be Number
return list;
}
}
As other colleagues pointed out the reason for issue is incorrect signature of parent method. The reason why the casting works is due to the way how compiler treats generics. It guarantees that there won't be runtime ClassCastException issues if you use generic but only if you don't do casting. As soon as you did it you actually said compiler to shut up as you know better what your type really is. However after this you potentially could get ClassCastException in runtime (not in this case I assume)
Given a class hierarchy where the base class defines a recursive self-type:
abstract class A<T extends A<T>> { }
How can I declare another class (which should not be generic in T, because such a T could vary over the lifetime of the object) with a field that can hold any subclass of A?
The following does not work:
public class B {
//fails to compile, because the capture of ? is not sufficiently narrow
private A<?> a;
public <T extends A<T>> setA(T a) {
this.a = a;
}
}
-- END OF QUESTION --
I've noticed a tendency of a number of StackOverflow members to approach certain difficult questions with "why are you doing that in the first place?" The following is a justification of my use of this pattern - you can note that the Java standard library also uses recursive self-types in its definition of the Enum class: Enum<E extends Enum<E>>. This question could similarly be asked as "how to define a field of type Enum<?>.
Justification example:
abstract class A<T extends A<T>> {
public abtract T self();
public B<T> bify(Bifyer bifyer) {
return bifyer.bify(self());
}
}
with subclasses:
class ASub1 extends A<ASub1> {
public ASub1 self() { return this; }
}
class ASub2 extends A<ASub2> {
public ASub2 self() { return this; }
}
bound to a parallel class hierarchy:
abstract class B<T extends A<T>> {
}
class BSub1<T extends A<T>> implements B<T> { }
class BSub2<T extends A<T>> implements B<T> { }
//and others
And with generation of B instances managed by implementations of a Bifyer interface:
interface Bifyer {
B<ASub1> bify(ASub1 asub1);
B<ASub2> bify(ASub2 asub2);
}
Implementations of this interface may return a BSub1 or BSub2 for the B. This is essentially an application of the Visitor pattern where the Bifyer is the visitor, but unlike the standard Visitor the accept method returns a value instead of void. This provides a modular framework where different Bifyer implementations can be specified to provide alternate behavior and return types for the Bify method - say one for each subclass of B.
If you bound the wildcard ? below by A, it should work:
public class B {
private A<? extends A> a;
public <T extends A<T>> void setA(T a) {
this.a = a;
}
}