Manoj
Manoj

Reputation: 5602

Tangled in generics

I have classes A, B with B extends A I have interface defined as

public interface MyProcessor<EVENT> {
     void processEvent(EVENT event);
}

I have two implementations

public class EventAProcessor implements EventProcessor<A> {
    @Override
    public void processEvent(A a) {
}
public class EventBProcessor implements EventProcessor<B> {
    @Override
    public void processEvent(B b) {
}

there is common processing so I decided to extend BProcessor from Aprocessor

public class EventBProcessor extends EventAProcessor implements EventProcessor<B> {

    }

This is where it fails with the message

 MyProcessor cannot be inherited with different arguments: <A> and <B>

I have other solutions to workaround my problem, but just wondering, how to get this working.

Upvotes: 1

Views: 111

Answers (5)

Lukas Eder
Lukas Eder

Reputation: 220762

You should introduce an abstract generic class:

public abstract class AbstractEventProcessor<EVENT> 
  implements EventProcessor<EVENT> {

  // Put your common logic here
}

Your other classes will then inherit common functionality as such:

public class EventAProcessor extends AbstractEventProcessor<A> {}
public class EventBProcessor extends AbstractEventProcessor<B> {}

This doesn't necessarily have to do with generics. It's a general way to approch polymorphism in object-oriented programming.

Upvotes: 2

Marko Topolnik
Marko Topolnik

Reputation: 200138

Don't make EventBProcessor extend EventAProcessor as it's not an is-a relationship. Reuse the functions you need either by pulling them into a common abstract class, or in a separate helper class that you reuse by composition. It's not always the best option to reuse through inheritance.

Upvotes: 4

Jens
Jens

Reputation: 17067

Add a shared "common" generic ancestor that requires A or a subclass thereof.

public abstract class ACommonProcessor<AEvent extends A> implements MyProcessor<AEvent> {
    ...
    // shared code goes here
}

public class EventBProcessor extends ACommonProcessor<B> {
    ...
    // B-specific code goes here
}

public class EventAProcessor extends ACommonProcessor<A> {
    ...
    // etc
}

Upvotes: 0

duffymo
duffymo

Reputation: 308733

I don't see how the interface has anything to do with either of your implementations. Neither of them implements the MyProcessor interface.

You also don't show any hierarchy for the Event class. What makes you think you can have different Event types with this arrangement?

Here's how I might do it:

public interface Event {
    String getName();
}

public interface EventProcessor<T extends Event> {
    void process(T event);
}

You don't need different EventProcessor implementations this way - the generic should be able to differentiate between different Event types. You'll only need a custom implementation if the process() method needs to change by type. You might way to think about a Visitor pattern if it does.

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 691625

If you want to reuse code through inheritance, the following should be OK:

public abstract AbstractEventAProcessor<T extends A> implements EventProcessor<T> {
    // common methods
}

public class EventAProcessor extends AbstractEventAProcessor<A> {
    @Override
    public void processEvent(A a) { ... }
}

public class EventBProcessor extends AbstractEventAProcessor<B> {
    @Override
    public void processEvent(B b) { ... }
}

Upvotes: 2

Related Questions