So lets take this example that I have a class A and class B both A and B are implementing a specific interface letters. Now I need to make a specific function in another class wherein I need to pass either A class object or B class object and similarly do some operation on these objects and return either A or B class objects. Now I can define the function using a generic type T but the catch is T must always implement interface letters.
So a Object of class 1 which doesn't implement interface letters wont be allowed to pass this function.
public class A implements letters{...}
public class B implements letters{...}
public class LetterOperations{
public T letterOp(T letter){..}
}
Here letterOp() must be accepting only those kind of generic classes T which implement interface letters.
Add type parameter bound when declaring generic class:
public class LetterOperations<T extends letter> {
public T letterOp(T letter){..}
}
Or use method with type parameter:
public <T extends letter> T letterOp(T letter){..}
Related
I have an Interface and 2 concrete class that implement that interface,
public interface ITemplate{}
public Template implements ITemoplate {}
public Template2 implements ITemplate {}
I have a method that takes in the Class object and instantiates it.
public addTemplate(Class<ITemplate> template){
pipe.add(template.newInstance())
}
The problem is that when I call that method, it throws a compile time error:
instance.addTemplate(Template.class)
Compile Time Error :
addTemplate(java.package.ITemplate.class) cannot be applied to addTemplate(java.package.Template.class)
Am I missing something, or is there a work around for this?
Class<ITemplate> will strictly accept the ITemplate.class
Class<? extends ITemplate> will accept any of the classes implementing ITemplate.class
try this method:
// works for all classes that inherit from ITemplate.
public addTemplate(Class< ? extends ITemplate> template){
pipe.add(template.newInstance())
}
instead of
// only accepts ITemplate Type Class (Strict Type).
public addTemplate(Class<ITemplate> template){
pipe.add(template.newInstance())
}
Here is an explanation: when you use Class<ITemplate> it is a strict type of class Itemplate. It will never take any other type argument other than ITemplate, because it is resolved at compile time only.
However Class <? extends ITemplate> can accept all objects that are either ITemplate or have ITemplate as a superclass.
I want to implement a super class and it is a java.util.concurrent.Callable . The child class will return different types of objects for Callable. Therefore, I want set this super class callable's generic type as to be any type. Following is my super class declaration.
public abstract class AbsTaskRunner implements java.util.concurrent.Callable {
I want to set generic type of Callable as any type.
public abstract class AbsTaskRunner implements java.util.concurrent.Callable <HERE_COMMON_TYPE> {
You can try with:
public abstract class AbsTaskRunner<T> implements java.util.concurrent.Callable<T>
Then the sub-classes can be either generic (like this):
public class GenericSubclass<T> extends AbsTaskRunner<T>
or extend AbsTaskRunner for some specific type (like this):
public class StringSubclass extends AbsTaskRunner<String>
So I'm creating an implementation of a priority queue using generics. I have this interface which I am trying to implement in my PriorityQueue class:
public interface PriorityQueueInterface<Item extends Comparable<Item>> { }
but I'm not sure what the proper syntax is to correctly implement the PriorityQueueInterface. Here is what I currently have:
public class PriorityQueue<Item extends Comparable<Item>> implements PriorityQueueInterface<Item extends Comparable<Item>>{ }
but it's throwing multiple errors. What would be the correct way to implement the interface? Any help would be appreciated.
You've already declared Item to be Comparable<Item> with the class definition of PriorityQueue. You only need to reference it in the implements clause, where you don't need to repeat that it's Comparable<Item>. You reference a generic type parameter in the implements or extends clause just as you would for any other part of the class body where the generic type parameter is in scope.
Try
public class PriorityQueue<Item extends Comparable<Item>>
implements PriorityQueueInterface<Item>{ /* implement here */ }
I try to do a generic class like this :
public abstract class MyClass<A extends MyInterface,B,C> implements A{
...
}
(Note: B and C are not interfaces, just other generic params)
I get a compilation error because there is absolutely no guarantee that A is an interface. Hence, the abstract class cannot implements A
Is there a way to tell the compiler that A must be an interface?
No,
Since you are using clause which after compilation will have following form like:
public abstract class MyClass implements java.lang.Object {
You can add implements MyInterface, B, C since that would check whether these interfaces are implemented.
Is it possible to inherit generic type and to force in the child class the type received?
Something like:
class A<GenericType>{}
class B extends A<GenericType>{}
Or:
class B <PreciseType> extends A <GenericType>{}
But where do I define the GenericType used in B?
Given
class A<T> {}
It depends on what you try to do, but both options are possible:
class B extends A<SomeType> {};
B bar = new B();
A<SomeType> foo = bar; //this is ok
and
class B<T> extends A<T>{}; //you could use a name different than T here if you want
B<SomeType> bar = new B<SomeType>();
A<SomeType> foo = bar; //this is ok too
But keep in mind that in the first case SomeType is an actual class (like String) and in the second case T is a generic type argument that needs to be instantiated when you declare/create objects of type B.
As a piece of advice: using generics in collections is easy and straightforward, but if you want to create your own generic classes you really need to understand them properly. There are a few important gotchas about their variance properties, so read the tutorial carefully and many times to master them.
Assuming A is declared as class A<T> {} and you want be to be specialised on String only for example, you can declare it as class B extends A<String>.
Example:
public class A<T> {
public T get() {
return someT;
}
}
public class B extends A<String> {
public String get() {
return "abcd";
}
}
class B extends A<GenericType>{}
This is possible. Your B class will be a new class that extends generic A class with specific class as parameter and B will not be a generic class.
class B <PreciseType> extends A <GenericType>{}
In this case you create a generic class B which has generic parameter PreciseType. This class B extends a specific version of A, but A's parameter doesn't depend on PreciseType.
If you want to create a generic class that has a parameter which is used in specification of parent class you can use the following:
class B <PreciseType> extends A <PreciseType>{}