Usage of extends in Class, Abstract, Interface combination - java

My main question revolves around when to use and what is the difference between the following when combined with Class, Abstract, Interface:
<E>
<E extends Interface>
<? extends Interface>
Shown below is a detailed question with some code signatures:
This code uses Guava Forwarding Decorators to define specific collections.
Base Interface:
public interface AnimalSetInterface<E extends AnimalI> extends Set<E>
This works:
public interface AsiaI<E extends AnimalI> extends AnimalSetInterface<E>
The following gives an error:
public interface AsiaI<E> extends AnimalSetInterface<E>
Bound mismatch: The type E is not a valid substitute for the bounded
parameter of the type AnimalSetInterface
What I am trying to understand is if I have specified at the Base Interface that I only want <E extends AnimalI> then why do I have to specify again in AsiaI?
I am trying to understand generics and at the same time minimize code.
Also if both classes have such code is there a good way to combine/minimize (remove/generify boilerplate code) it:
Asia:
public Asia(final ImmutableSet<E> animalSet){
super(animalSet);
}
public static <E extends AnimalI> AsiaI<E> of(final ImmutableSet<E> animalSet){
return new Asia(animalSet);
}
Africa:
public Africa(final ImmutableSet<E> animalSet){
super(animalSet);
}
public static <E extends AnimalI> AfricaI<E> of(final ImmutableSet<E> animalSet){
return new Africa(animalSet);
}

public class Africa<E extends AnimalI> extends AnimalSetAbstract implements AfricaI
public class Asia<E> extends AnimalSetAbstract implements AsiaI
The difference is that in the first case, your generic type must extend AnimalI
In the second case, your generic type could be any class.

Related

Using bound on a parameterized type

I am creating an interface and an implementation of linked list like so in Java 1.8:
public interface MyList<E extends Comparable<E>> {
.....
}
public class MyListImpl<E> implements MyList<E extends Comparable<E>>{
......
}
The interface has no compiler issues but the MyListImpl is giving an error Unexpected Bound where I have E extends Comparable<E>>. I am not sure why this error is happening though.
The bounds always go on the declaration of the generic type. That's the one at the end of the class name. The one in the implements clause is using the already declared type. So: public class MyListImpl<E extends Comparable<E>> implements MyList<E>.
If you want to make it a bit better, use <E extends Comparable<? super E>>. That looks the same but isn't; with just Comparable<E> you won't be able to support classes like java.sql.Timestamp, which extends java.util.Date which implements Comparable<Date>. In other words: Timestamp is not Comparable<Timestamp> but Comparable<Date>, and using Comparable<? super E> will allow you to use it.

The generic type upper bound to be generic itself

I'm creating a generic interface and its class implementation. It's a disjoint set. The generic type upper boundary for this class is generic itself:
public class MyDisjointSet<K extends Pair<T, T>> implements IMyDisjointSet<K> {
}
and
public interface IMyDisjointSet<T> {}
but I get compile error Cannot resolve symbol T.
When I add a second parameter to the list of generic types it works compiles:
public class MyDisjointSet<K extends Pair<T, T>, T> implements IMyDisjointSet<K>
Why should we put T here? why not before class name?
Please try
public class MyDisjointSet<K extends Pair<T, T>,T> implements IMyDisjointSet<K> {

How make a generic type in java?

I want make my List. But I dont know how to write generic type in java.
public interface myListInt <E extends Comparable<E>>{}
public class myList<E extends myListInt<E>> extends LinkedList{}
When I am doing that, it gives an error.How should ı write.
The exact intent of your code is unclear, but I got an error for the <E> in myListInt<E>.
public interface myListInt <E extends Comparable<E>>{}
public class myList<E extends myListInt<E>> extends LinkedList{}
^ Error here
This is because you need to constrain E to extend Comparable<E> in order to be a valid bound for myListInt<E>:
public class myList<E extends Comparable<E> & myListInt<E>>
extends LinkedList{}
However, you maybe also want to add a constraint to LinkedList too (assuming this is java.util.LinkedList:
public class myList<E extends Comparable<E> & myListInt<E>>
extends LinkedList<E> {}

Implementing a Generic Interface In Java

I am new to Java Generics. I have to implement an interface which is of generic type. The syntax is as follows:
public interface A{}
public interface B<T extends A>{
public T methodB(T a) ;
}
Now I have to implement B so Lets say my Class is C
public class C implements B<T extends A>{}
The java compiler is not letting me use it this way. Also I do not want to use raw types. Please help.
It should be
public class C<T extends A> implements B<T>
The type parameter is declared following the class name, and later can be used in the implements clause.
If your implementing class is still a generic type you have to use this syntax:
public class C<T extends A> implements B<T> {}
As explained by Eran.
If C is not generic you simply need to specify the type argument for your interface:
public class C implements B<TypeExtendingA> {}
Where TypeExtendingA implements or extends A (or is A)

Generics and type inference for a generic factory

Sorry in advance for any bad english language in this question.
I have in mind to create a sort of factory which can only create instances of classes defined in a list implemented by a concrete factory instance class. First, i defined this interface :
public interface ValuesSystem {
public interface AllowedValue<T extends Class<? extends SystemValue>>{};
AllowedValue<Class<? extends SystemValue>> getAllowedValue(Enum<?> id);
Map<? extends Enum<?>, AllowedValue<Class<? extends SystemValue>>> getAllowedValues();
<T extends SystemValue> T create(AllowedValue<Class<T>> allowedClass, ValueData data) throws InvalidValueException;
}
The interface AllowedValue is just a "marker wrapper" interface using generics to define a Class instance "allowed" to be create by my factory.
The getAllowedValue is a method used to get a wrapped allowed Class instance from my allowed Class "list" using an internal enumeration from a concrete class implementing this interface (example of a concrete class will come).
The create method is intended to finally create an instance of my allowed Class instance given in the allowedClass argument.
Here is an example of a concrete class implementing this interface :
public class BasicValueSystem implements ValuesSystem {
public BasicValueSystem() {
super();
allowedValues = (Map<VALUES_ID, AllowedValue<Class<? extends SystemValue>>>) getAllowedValues();
}
public static enum VALUES_ID {
MODIFIER
}
private static Map<VALUES_ID, AllowedValue<Class<? extends SystemValue>>> allowedValues;
private class BasicAllowedValue<T extends Class<? extends SystemValue>>
implements AllowedValue<Class<? extends SystemValue>> {
}
#Override
public <T extends SystemValue> T create(
AllowedValue<Class<T>> allowedClass, ValueData data)
throws InvalidValueException {
if (!(allowedClass instanceof BasicAllowedValue)) {
throw new InvalidValueException();
}
return null;
}
#Override
public AllowedValue<Class<? extends SystemValue>> getAllowedValue(Enum<?> id) {
return allowedValues.get(id);
}
#Override
public Map<? extends Enum<?>, AllowedValue<Class<? extends SystemValue>>> getAllowedValues() {
Map<VALUES_ID, AllowedValue<Class<? extends SystemValue>>> allowed = new EnumMap<VALUES_ID, AllowedValue<Class<? extends SystemValue>>>(VALUES_ID.class);
allowed.put(VALUES_ID.MODIFIER, new BasicAllowedValue<Class<ModifierValue>>());
return allowed;
}
}
For the moment the create method return null, but the problem is elsewhere and this not the point of my question
The problem occurs when I tried to create an instance of one of my "allowed" values instance with the following code :
BasicValueSystem bvs = new BasicValueSystem();
AllowedValue<Class<? extends SystemValue>> allowed = bvs
.getAllowedValue(BasicValueSystem.VALUES_ID.MODIFIER);
bvs.create(allowed, new ModifierValueData());
The compiler tells me :
The method create(ValuesSystem.AllowedValue<Class<T>>, ValueData) in the type BasicValueSystem is not applicable for the arguments (ValuesSystem.AllowedValue<Class<? extends SystemValue>>, ModifierValueData)
I think i missed something concerning the type inference made by generics in general.
Can anyone can explain me the create method signature is not applicable in this case and how to fix it ?
Thanks in advance for taking your time.
Note that public interface AllowedValue<T extends Class<? extends SystemValue>> does not make much sense. The only valid type for T would be Class<? extends SystemValue> as the class Class is final and can’t have subclasses. So you can replace it with interface AllowedValue<Class<? extends SystemValue>> without any change in the semantic, but what you really mean (imho) is interface AllowedValue<T extends SystemValue>. Don’t mess around with Class in a type signature. The interface still might have methods referring to Class<T> then.
public interface ValuesSystem {
public interface AllowedValue<T extends SystemValue>{};
AllowedValue<? extends SystemValue> getAllowedValue(Enum<?> id);
public <T extends SystemValue> T create
(AllowedValue<T> allowedClass, ValueData data);
}
Adapt the implementation accordingly, BasicAllowedValue becomes
private class BasicAllowedValue<T extends SystemValue> implements AllowedValue<T>
Then your problem with the using code disappears.
BasicValueSystem bvs = new BasicValueSystem();
AllowedValue<? extends SystemValue> allowed = bvs
.getAllowedValue(BasicValueSystem.VALUES_ID.MODIFIER);
bvs.create(allowed, new ModifierValueData());
will compile.
Note that if AllowedValue shall remain a marker interface without methods only, it is unnecessary, Class<T> already fulfills this role. It will also work when doing it like this:
public interface ValuesSystem {
Class<? extends SystemValue> getAllowedValue(Enum<?> id);
public <T extends SystemValue> T create(Class<T> allowedClass, ValueData data);
}
and
BasicValueSystem bvs = new BasicValueSystem();
Class<? extends SystemValue> allowed = bvs
.getAllowedValue(BasicValueSystem.VALUES_ID.MODIFIER);
bvs.create(allowed, new ModifierValueData());

Categories

Resources