Extending functionality of all implementations of an Interface? - java

I'm looking to create a set of functions which all implementations of a certain Interface can be extended to use. My question is whether there's a way to do this without using a proxy or manually extending each implementation of the interface?
My initial idea was to see if it was possible to use generics; using a parameterized type as the super type of my implementation...
public class NewFunctionality<T extends OldFunctionality> extends T {
//...
}
...but this is illegal. I don't exactly know why this is illegal, but it does sort of feel right that it is (probably because T could itself be an interface rather than an implementation).
Are there any other ways to achieve what I'm trying to do?
EDIT One example of something I might want to do is to extend java.util.List... Using my dodgy, illegal syntax:
public class FilterByType<T extends List> extends T {
public void retainAll(Class<?> c) {
//..
}
public void removeAll(Class<?> c) {
//..
}
}

You can achieve something like this using a programming pattern known as a 'decorator' (although if the interface is large then unfortunately this is a bit verbose to implement in Java because you need to write single-line implementations of every method in the interface):
public class FilterByType<T> implements List<T> {
private List<T> _list;
public FilterByType(List<T> list) {
this._list = list;
}
public void retainAll(Class<?> c) {
//..
}
public void removeAll(Class<?> c) {
//..
}
// Implement List<T> interface:
public boolean add(T element) {
return _list.add(element);
}
public void add(int index, T element) {
_list.add(index, element);
}
// etc...
}
Alternatively, if the methods don't need to access protected members, then static helper methods are a less clucky alternative:
public class FilterUtils {
public static void retainAll(List<T> list, Class<?> c) {
//..
}
public static void removeAll(List<T> list, Class<?> c) {
//..
}
}

What prevents you from just adding new methods to the interface?
If you can't just add the new functionality to old interface, you could consider making another interface and then an implementation which merely implements those two. Just to be clear, in code this is what I mean:
// Old functionality:
public interface Traveling {
void walk();
}
// Old implementation:
public class Person implements Traveling {
void walk() { System.out.println("I'm walking!"); }
}
// New functionality:
public interface FastTraveling {
void run();
void fly();
}
// New implementation, option #1:
public class SuperHero extends Person implements FastTraveling {
void run() { System.out.println("Zoooom!"); }
void fly() { System.out.println("To the skies!"); }
}
// New implementation, option #2:
public class SuperHero implements Traveling, FastTraveling {
void walk() { System.out.println("I'm walking!"); }
void run() { System.out.println("Zoooom!"); }
void fly() { System.out.println("To the skies!"); }
}

I think it's illegal because you can not guarantee what class T will be. Also there are technical obstacles (parent's class name must be written in bytecode, but Generics information get lost in bytecode).
You can use Decorator pattern like this:
class ListDecorator implements List {
private List decoratingList;
public ListDecorator(List decoratingList){
this.decoratingList = decoratingList;
}
public add(){
decoratingList.add();
}
...
}
class FilterByArrayList extends ListDecorator {
public FilterByAbstractList () {
super(new ArrayList());
}
}

There is a delegation/mixin framework that allows a form of this. You can define a new interface, implement a default implementation of that interface, then request classes which implement that interface but subclass from elsewhere in your hierarchy.
It's called mixins for Java, and there's a webcast right there that demonstrates it.

I'm afraid it's not clear what do you want to get.
Basically, I don't see any benefit in using 'public class NewFunctionality<T extends OldFunctionality> extends T' in comparison with 'public class NewFunctionality extends OldFunctionality' ('public class FilterByType<T extends List> extends T' vs 'public class FilterByType<T> implements List<T>')

Related

Java abstract class with generic parameter that implements its own generic parameter

I'm facing a tricky problem.
I'm trying to do create a callback manager generic class that takes a generic of any kind of interfaces. The plan is, to do something like that:
public interface LocationListener {
void locationChanged();
void providerChanged();
}
//The implementation declaration below is wrong...
public abstract class CallbackManager<T> implements T {
//do something
}
public class MyCallbackManager extends CallbackManager<LocationListener> {
#Override
public void locationChanged() {
}
#Override
public void providerChanged() {
}
}
Generally spoken, I try to avoid to build the MyCallbackManager class like that:
public class MyCallbackManager extends CallbackManager<LocationListener> implements LocationListener {
#Override
public void locationChanged() {
}
#Override
public void providerChanged() {
}
}
Is there a way to achieve that?
I'm looking forward to your responses.
EDIT
Because you asked for a clarification of the use case. This is the idea behind it:
public abstract class CallbackManager<T> {
protected interface FunctionalInterface<T> {
void run(T type);
}
protected ArrayList<WeakReference<T>> eventQueue = new ArrayList<>();
protected void flush(#NonNull FunctionalInterface<T> functionalInterface) {
for (int i = eventQueue.size() - 1; i >= 0; i--) {
WeakReference<T> weakReference = eventQueue.get(i);
T type = weakReference.get();
if (type == null) {
unregister(i);
} else {
functionalInterface.run(type);
}
}
}
}
public class CallbackManagerLocation extends CallbackManager<LocationListener> implements LocationListener {
#Override
public void locationChanged() {
flush((ll) -> ll.locationChanged());
}
#Override
public void providerChanged() {
flush((ll) -> ll.providerChanged());
}
}
The implemented interface in CallbackManagerLocation is only used to have exactly the same naming convention like the interface that is hold in the CallbackManager.
Sorry, but this is not allowed. The amount of problems resulting from this would be enormous. For example imagine if you had a function public T locationChanged() in CallbackManager. This would violate the interface without being obvious in the CallbackManager class. And a lot more such examples.
No, You cannot do like that,
public abstract class CallbackManager<T> implements T
It will throw compile time error as class T is not describing actual type of reference that is implemented by your abstract class as per class loading mechanism provided in JAVA doc.
There is another way so you can do as follow,
public abstract class CallbackManager<ParentListener> implements ParentListener.
but you will get error message like Cannot refer to the type parameter LocationListener as a supertype
And it is not needed in any scenario, If exists there is alternate way for its answer

Implement Two EventHandlers [duplicate]

I have a generic interface
public interface Consumer<E> {
public void consume(E e);
}
I have a class that consumes two types of objects, so I would like to do something like:
public class TwoTypesConsumer implements Consumer<Tomato>, Consumer<Apple>
{
public void consume(Tomato t) { ..... }
public void consume(Apple a) { ...... }
}
Apparently I can't do that.
I can of course implement the dispatch myself, e.g.
public class TwoTypesConsumer implements Consumer<Object> {
public void consume(Object o) {
if (o instanceof Tomato) { ..... }
else if (o instanceof Apple) { ..... }
else { throw new IllegalArgumentException(...) }
}
}
But I am looking for the compile-time type-checking and dispatching solution that generics provide.
The best solution I can think of is to define separate interfaces, e.g.
public interface AppleConsumer {
public void consume(Apple a);
}
Functionally, this solution is OK, I think. It's just verbose and ugly.
Any ideas?
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);
}
}
Because of type erasure you can't implement the same interface twice (with different type parameters).
Here's a possible solution based on Steve McLeod's one:
public class TwoTypesConsumer {
public void consumeTomato(Tomato t) {...}
public void consumeApple(Apple a) {...}
public Consumer<Tomato> getTomatoConsumer() {
return new Consumer<Tomato>() {
public void consume(Tomato t) {
consumeTomato(t);
}
}
}
public Consumer<Apple> getAppleConsumer() {
return new Consumer<Apple>() {
public void consume(Apple a) {
consumeApple(t);
}
}
}
}
The implicit requirement of the question was Consumer<Tomato> and Consumer<Apple> objects that share state. The need for Consumer<Tomato>, Consumer<Apple> objects comes from other methods that expect these as parameters. I need one class the implement them both in order to share state.
Steve's idea was to use two inner classes, each implementing a different generic type.
This version adds getters for the objects that implement the Consumer interface, which can then be passed to other methods expecting them.
At least, you can make a small improvement to your implementation of dispatch by doing something like the following:
public class TwoTypesConsumer implements Consumer<Fruit> {
Fruit being an ancestor of Tomato and Apple.
just Stumbled upon this. It just happened, that I had the same Problem, but I solved it in a different way:
I just created a new Interface like this
public interface TwoTypesConsumer<A,B> extends Consumer<A>{
public void consume(B b);
}
unfortunately, this is considered as Consumer<A> and NOT as Consumer<B> against all Logic. So you have to create a small Adapter for the second consumer like this inside your class
public class ConsumeHandler implements TwoTypeConsumer<A,B>{
private final Consumer<B> consumerAdapter = new Consumer<B>(){
public void consume(B b){
ConsumeHandler.this.consume(B b);
}
};
public void consume(A a){ //...
}
public void conusme(B b){ //...
}
}
if a Consumer<A> is needed, you can simply pass this, and if Consumer<B> is needed just pass consumerAdapter
In Functional style it is quite easy do this without implementing the interface and also it does the compile time type checking.
Our functional interface to consume entity
#FunctionalInterface
public interface Consumer<E> {
void consume(E e);
}
our manager to process and consume entity appropriately
public class Manager {
public <E> void process(Consumer<E> consumer, E entity) {
consumer.consume(entity);
}
public void consume(Tomato t) {
// Consume Tomato
}
public void consume(Apple a) {
// Consume Apple
}
public void test() {
process(this::consume, new Tomato());
process(this::consume, new Apple());
}
}
You cannot do this directly in one class as the class definition below cannot be compiled due to erasure of generic types and duplicate interface declaration.
class TwoTypesConsumer implements Consumer<Apple>, Consumer<Tomato> {
// cannot compile
...
}
Any other solution for packing the same consume operations in one class requires to define your class as:
class TwoTypesConsumer { ... }
which is pointless as you need to repeat/duplicate the definition of both operations and they won't be referenced from interface. IMHO doing this is a bad small and code duplication which I'm trying to avoid.
This might be an indicator also that there is too much responsibility in one class to consume 2 different objects (if they aren't coupled).
However what I'm doing and what you can do is to add explicit factory object to create connected consumers in the following way:
interface ConsumerFactory {
Consumer<Apple> createAppleConsumer();
Consumer<Tomato> createTomatoConsumer();
}
If in reality those types are really coupled (related) then I would recommend to create an implementation in such way:
class TwoTypesConsumerFactory {
// shared objects goes here
private class TomatoConsumer implements Consumer<Tomato> {
public void consume(Tomato tomato) {
// you can access shared objects here
}
}
private class AppleConsumer implements Consumer<Apple> {
public void consume(Apple apple) {
// you can access shared objects here
}
}
// It is really important to return generic Consumer<Apple> here
// instead of AppleConsumer. The classes should be rather private.
public Consumer<Apple> createAppleConsumer() {
return new AppleConsumer();
}
// ...and the same here
public Consumer<Tomato> createTomatoConsumer() {
return new TomatoConsumer();
}
}
The advantage is that the factory class knows both implementations, there is a shared state (if needed) and you can return more coupled consumers if needed. There is no repeating consume method declaration which aren't derived from interface.
Please note that each consumer might be independent (still private) class if they aren't completely related.
The downside of that solution is a higher class complexity (even if this can be a one java file) and to access consume method you need one more call so instead of:
twoTypesConsumer.consume(apple)
twoTypesConsumer.consume(tomato)
you have:
twoTypesConsumerFactory.createAppleConsumer().consume(apple);
twoTypesConsumerFactory.createTomatoConsumer().consume(tomato);
To summarize you can define 2 generic consumers in one top-level class using 2 inner classes but in case of calling you need to get first a reference to appropriate implementing consumer as this cannot be simply one consumer object.
Another alternative to avoid the use of more classes. (example using java8+)
// Mappable.java
public interface Mappable<M> {
M mapTo(M mappableEntity);
}
// TwoMappables.java
public interface TwoMappables {
default Mappable<A> mapableA() {
return new MappableA();
}
default Mappable<B> mapableB() {
return new MappableB();
}
class MappableA implements Mappable<A> {}
class MappableB implements Mappable<B> {}
}
// Something.java
public class Something implements TwoMappables {
// ... business logic ...
mapableA().mapTo(A);
mapableB().mapTo(B);
}
Sorry for answer old questions, but I really love it! Try this option:
public class MegaConsumer implements Consumer<Object> {
Map<Class, Consumer> consumersMap = new HashMap<>();
Consumer<Object> baseConsumer = getConsumerFor(Object.class);
public static void main(String[] args) {
MegaConsumer megaConsumer = new MegaConsumer();
//You can load your customed consumers
megaConsumer.loadConsumerInMapFor(Tomato.class);
megaConsumer.consumersMap.put(Apple.class, new Consumer<Apple>() {
#Override
public void consume(Apple e) {
System.out.println("I eat an " + e.getClass().getSimpleName());
}
});
//You can consume whatever
megaConsumer.consume(new Tomato());
megaConsumer.consume(new Apple());
megaConsumer.consume("Other class");
}
#Override
public void consume(Object e) {
Consumer consumer = consumersMap.get(e.getClass());
if(consumer == null) // No custom consumer found
consumer = baseConsumer;// Consuming with the default Consumer<Object>
consumer.consume(e);
}
private static <T> Consumer<T> getConsumerFor(Class<T> someClass){
return t -> System.out.println(t.getClass().getSimpleName() + " consumed!");
}
private <T> Consumer<T> loadConsumerInMapFor(Class<T> someClass){
return consumersMap.put(someClass, getConsumerFor(someClass));
}
}
I think that is what you are looking for.
You get this output:
Tomato consumed!
I eat an Apple
String consumed!

What is the correct way to override method of interface from a child interface using generics?

I have those two interfaces:
public interface ApiResultCallback {
void onSuccess(RestApi.Success<?> successResult);
void onFailure(RestApi.Failure failureResult);
}
public interface GetHappyCowsCallback extends ApiResultCallback {
void onSuccess(RestApi.Success<List<HappyCow>> successResult);
}
Where Success and Failure are:
public static class Success<T> extends ApiResult {
public T data;
}
public static class Failure extends ApiResult {
public String message;
}
I get an error in GetCleverPointsCallback interface saying that
both methods have same erasure but neither overrides the other.
What does that mean? Shouldn't the method from GetHappyCowsCallback override the method of its parent?
What I'm trying to achieve here is some kind of mapping between callbacks and their data without having to implement long mapping functions or even worse, duplicating the Success class like this:
public static abstract class Success<T> extends ApiResult {
public T data;
}
public static class ListHappyCowSuccess extends Success<List<HappyCow>> {
}
void onSuccess(RestApi.Success<?> successResult);
And
void onSuccess(RestApi.Success<List<HappyCow>> successResult);
Do not have the same signature. So the second does not override the first
What you're trying to do can be achieved by making the interface generic:
public interface ApiResultCallback<T> {
void onSuccess(RestApi.Success<T> successResult);
void onFailure(RestApi.Failure failureResult);
}
public interface GetHappyCowsCallback extends ApiResultCallback<List<HappyCow>> {
}
In fact, you probably don't need the second interface at all. Such pseudo-typedefs are even considered an anti-pattern, because the new types cannot be exchanged with their equivalents.
If I have a method like this:
void myMethod(GetHappyCowsCallback callback);
I can not pass an ApiResultCallback<List<HappyCow>> to it.
In most cases interface overriding doesn't really make sense. Unless it involves default methods:
interface InterfaceA {
public void doSomething();
}
interface InterfaceB extends InterfaceA {
#Override
public default void doSomething() {...} // Provides a default implementation
}

Java Method with generic class as argument

It is possible write a method in java with generic class with argumet??
example:
public void Transfer (class c){
class.Search();
}
Yes, you would need to do something like so:
public class Foo<T> {
public void Transfer(T c) {
c.Search();
}
}
Since you seem to want to invoke a specific method, you might want to define an interface which provides the methods you are after, and bind the generic constraint with it:
public interface MyInt {
void Search();
}
....
public class Foo<T extends MyInt> {
public void Transfer(T c) {
c.Search();
}
}
Alternatively:
public class Foo {
public void Transfer(MyInt c) {
c.Search();
}
}
The last example does away with generics and uses interfaces, which can sometimes yield code which is easier to follow, depending on what you are trying to achieve.

Returning values from child-classes

I want to be able to call the ObjectAction#firstClick in a dynamic way which has support for more classes. My goal is not to access the Test class directly and call it from there.
Keep in mind you may not use static contexts.
public abstract class ObjectAction implements AchievementListener {
public abstract void firstClick(GameObject object);
}
firstClick is what I want to call in a dynamic way..
Here is more code..
public interface AchievementListener {
}
This acts as the listener type which has child-classes such as ObjectAction, ItemAction, GroundAction etc.
Here is the enum
public enum Achievements {
TEST(new ObjectAction() {
#Override
public void firstClick(Object object) {
}
});
private static final Set<Achievements> ACHIEVEMENTS = Collections.unmodifiableSet(
EnumSet.allOf(Achievements.class));
public static Optional<AchievementListener> getListener() {
return ACHIEVEMENTS.stream().filter(a -> a.listener).findAny();
}
AchievementListener listener;
Achievements(AchievementListener listener) {
this.listener = listener;
}
}
The #getListener() function is the part I need help with, it doesn't work atm because it isnt'returning an AchievementListener, what i'm looking for is something like getListener().getObjectActions().firstClick(GameObject object); and for something like ItemActions it should be getListener().getItemActions().executeAction(Item item);
You have created an interface which doesn't declare any methods. Then you implement that interface at an abstract class which only declares that one abstract method; thus you don't need that abstract class because you are not doing anything with a necessary constructor. Read more on abstract classes and interfaces here.
What you need to do is to declare the interface like this:
public interface AchievementListener {
public void firstClick(GameObject object); // Declared the interface method
}
You can leave the abstract class now because it has no use and directly ask for a AchievementListener:
public class Test extends Achievement {
#Override
public AchievementListener process (Player player) {
return new AchievementListener () {
#Override
public void firstClick(GameObject object) {
System.out.println("This works for sure ;)");
}
};
}
}
So in short, the dynamic is in the interface, because you want that one method in all of your child classes!

Categories

Resources