How to make a Java class that implements one interface with two generic types?
Consider encapsulation:
public class TwoTypesConsumer {
private TomatoConsumer tomatoConsumer = new TomatoConsumer();
private AppleConsumer appleConsumer = new AppleConsumer();
public void consume(Tomato t) {
tomatoConsumer.consume(t);
}
public void consume(Apple a) {
appleConsumer.consume(a);
}
public static class TomatoConsumer implements Consumer<Tomato> {
public void consume(Tomato t) { ..... }
}
public static class AppleConsumer implements Consumer<Apple> {
public void consume(Apple a) { ..... }
}
}
If creating these static inner classes bothers you, you can use anonymous classes:
public class TwoTypesConsumer {
private Consumer<Tomato> tomatoConsumer = new Consumer<Tomato>() {
public void consume(Tomato t) {
}
};
private Consumer<Apple> appleConsumer = new Consumer<Apple>() {
public void consume(Apple a) {
}
};
public void consume(Tomato t) {
tomatoConsumer.consume(t);
}
public void consume(Apple a) {
appleConsumer.consume(a);
}
}
How to implement the same interface multiple times, but with different generics?
You need to use inner or anonymous classes. For instance:
class Foo {
public EventListener<X> asXListener() {
return new EventListener<X>() {
// code here can refer to Foo
};
}
public EventListener<Y> asYListener() {
return new EventListener<Y>() {
// code here can refer to Foo
};
}
}
Implementing multiple generic interfaces
There is only one handle(Object) method in reality. You are effectively write the same as
public class CompositeListener implements EventListener {
public void handle(Object event) {
if (event instanceof PriceUpdate) {
///
} else if (event instanceof OrderEvent) {
///
}
}
}
Without this checking logic, you can't effectively call your event listener in any case.
Generic which is required to implement two interfaces
you can use Multiple Bounds
like <T extends CanFly & CanRun>
Note: in future if you want to add a class along with CanFly & CanRun
then make sure to put the class at the beginning like <T extends className & CanFly & CanRun>
otherwise it will raise an exception
Java Generics With a Class & an Interface - Together
Actually, you can do what you want. If you want to provide multiple interfaces or a class plus interfaces, you have to have your wildcard look something like this:
<T extends ClassA & InterfaceB>
See the Generics Tutorial at sun.com, specifically the Bounded Type Parameters section, at the bottom of the page. You can actually list more than one interface if you wish, using & InterfaceName
for each one that you need.
This can get arbitrarily complicated. To demonstrate, see the JavaDoc declaration of Collections#max
, which (wrapped onto two lines) is:
public static <T extends Object & Comparable<? super T>> T
max(Collection<? extends T> coll)
why so complicated? As said in the Java Generics FAQ: To preserve binary compatibility.
It looks like this doesn't work for variable declaration, but it does work when putting a generic boundary on a class. Thus, to do what you want, you may have to jump through a few hoops. But you can do it. You can do something like this, putting a generic boundary on your class and then:
class classB { }
interface interfaceC { }
public class MyClass<T extends classB & interfaceC> {
Class<T> variable;
}
to get variable
that has the restriction that you want. For more information and examples, check out page 3 of Generics in Java 5.0. Note, in <T extends B & C>
, the class name must come first, and interfaces follow. And of course you can only list a single class.
How can I define a generic class that implements two interfaces?
You can give multiple bounds to type parameter:
public interface AbstractSortedSimpleList<T extends Comparable<T> & Alike>
Then, your SortedSimpleList
would be like:
class SortedSimpleList<T extends Comparable<T> & Alike> implements AbstractSortedSimpleList<T> {}
See JLS §4.4:
Every type variable declared as a type parameter has a bound. If no bound is declared for a type variable, Object is assumed. If a bound is declared, it consists of either:
a single type variable T, or
a class or interface type T possibly followed by interface types I1 & ... & In.
Note:
You can't have such multiple bounds for wildcards though. It's only for type parameters.
References:
- Java Generics FAQs - Type Parameter bounds
How to implement a generic interface that extends another generic interface in Java?
I think it's worth inspecting which identifier means what in this case. Let's look at the base interface first GenericItemProviderInterface<Req, ExtReq, ExtRes, Res>
.
Here all 4 type parameters Req
, ExtReq
, ExtRes
and Res
are type parameters. That's important to remember, because they are not themselves types!
Then let's look at the definition of the derived interface: ItemsProviderInterface<ExtReq, ExtRes>
only has 2 type parameters: ExtReq
and ExtRes
. Note that despite the identical names, those don't inherently have anything to do with the ones on the base interface. That connection comes now:
interface ItemsProviderInterface<ExtReq, ExtRes>
extends GenericItemProviderInterface<ItemRequest, ExtReq, ExtRes, ItemResponse>
This means that an ItemsProviderInterface
is-a GenericProviderInterface
with the 4 type parameters set like this:
Req
ofGenericItemProviderInterface
is set to the actual type (class or interface)ItemRequest
.ExtReq
ofGenericItemProviderInterface
is set to the type parameterExtReq
ofItemsProviderItnerface
ExtRes
ofGenericItemProviderInterface
is set ot the type parameterExtRes
ofItemsProviderInterface
Res
ofGenericItemProviderInterface
is set to the actual typeItemResponse
.
So 2 of the 4 type parameters of the base-class are "fixed" to a specific type and the remaining two are left variable.
If you now implement ItemProviderInterface
you could either also have 2 type parameters and route them to ExtReq
/ExtRes
or fix them to specific classes (or do 1-and-1, but that's probably not useful for this specific example.
So either
class MyItemProvider<ExtReq, ExtRes>
implements ItemProviderInterface<ExtReq, ExtRes> {...}
or
class MySpecificItemProvider
implements ItemProviderInterface<MySpecificExtReq, MySpecificExtRes> {...}
Is it possible to have two different generic types (such as T) in a Java interface?
Yes you can have multiple generic types.
public interface Processor<T, S> {
T update( S id );
T find( S id );
List<T> findAll( List<S> ids );
}
Implementing Generic Interface in Java
You can't do that in Java. You can only implement one concrete realization of the same generic interface. I would do this instead:
public class AddressHandler implements Handles<Event>{
public void handle(Event e){
if(e instanceof AddressDiscarded){
handleDiscarded(e);
} else if(e instanceof AddressChanged){
handleChanged(e);
}
}
public void handleDiscarded(AddressDiscarded e){}
public void handleChanged(AddressChanged e){}
}
Related Topics
Get Maven Artifact Version at Runtime
How to Combine Two Hashmap Objects Containing the Same Types
Static Versus Non-Static Lock Object in Synchronized Block
Variable's Scope in a Switch Case
What Does an Exclamation Mark Mean in Java
Spring Resttemplate Get with Parameters
How to Initialize an Arraylist with All Zeroes in Java
Using Jaxb to Unmarshal/Marshal a List<String>
Should I Close the Servlet Outputstream
How to Convert a String to Another Locale
Why Does (360/24)/60 = 0 ... in Java
Spring Boot How to Hide Passwords in Properties File
Case Insensitive String as Hashmap Key
Dynamically Change Spring Data Source
How to Set Dpi Information in an Image
Compiler Error When Declaring a Variable Inside If Condition and No Curly Braces