Tangled in generics - java

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.

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.

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.

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) { ... }
}

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.

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
}

Related

In Java, is it OK to require classes that implement an interface to inherit from a specific base class?

Quick style question:
I have a Java interface that defines functions that must be implemented by classes in a particular hierarchy, all descended from a specific base class.
There are contexts where I will be dealing with these classes through a pointer to the interface, but I need a pointer to the base class instead.
Example:
public class Base {}
public interface ChildRequirements {
Base asBase();
}
public class Child extends Base implements ChildRequirements {
Base asBase() { return this; }
}
public class SomeClass {
public void doSomething(Base base) { }
public void doSomethingElse(ChildRequirements creqt) {
doSomething(creqt.asBase());
}
}
Is this bad form? Am I thinking about this the wrong way? Should I just cast creqt as Base and ignore the warnings?
I have a Java interface that defines functions that must be implemented by classes in a particular hierarchy, all descended from a specific base class.
Then it isn't an interface, it's an abstract base class. Get rid of ChildRequirements and instead have Base define the requirements and mark it abstract:
abstract public class Base {
// ...required methods here, `abstract` if you don't have a
// base implementation...
}
public class Child extends Base {
// ...implements any `abstract` methods...
}
public class SomeClass {
public void doSomething(Base base) { }
public void doSomethingElse(Base creqt) {
doSomething(creqt);
}
}
But whenever possible, program to interfaces, not abstract classes.
I don't see the difference between your typing and just using interfaces and ol'regular inheritance. Your return this in the Child class seems to suggest you expect it to be a subtype of Base. The way the interfaces are structured it seems like you are actually expressing an is-a relationship between Base and ChildRequirements, but decorating the super class.
Alternate typing:
//Straight-forware inheritance
public interface Base {
}
interface ChildRequirements extends Base{
Base asBase();//return the super
}
class Child implements ChildRequirements {
public Base asBase() { return this;}
}
class SomeClass {
public void doSomething(Base base) { }
public void doSomethingElse(ChildRequirements creqt) {
doSomething(creqt.asBase());
}
}

Checking `instanceof` while iterating through a loop

I have class structure where
public abstract class AbstractBuilding implements some non-relevant
interfaces for this question.
public abstract class AbstractAnimalBuilding extends AbstractBuiling
And small number of classes following this structure:
public class AnimalBuildingA extends AbstractAnimalBuilding
public class AnimalBuildingB extends AbstractAnimalBuilding
public class AnimalBuildingC extends AbstractAnimalBuilding
public class AnimalBuildingD extends AbstractAnimalBuilding
In a totally separate class I have the following method:
#FXML
private Button btnAnimalBuildingA;
#FXML
private Button btnAnimalBuildingB;
#FXML
private Button btnAnimalBuildingC;
#FXML
private Button btnAnimalBuildingD;
for (AbstractAnimalBuilding animalBuilding: animalBuildings){
if (animalBuilding instanceof AnimalBuildingA) {
changeButtonDisplay(btnAnimalBuildingA)
} else if (animalBuilding instanceof AnimalBuildingB){
changeButtonDisplay(btnAnimalBuildingB)
} else if (animalBuilding instanceof AnimalBuildingC) {
changeButtonDisplay(btnAnimalBuildingC)
} else if (animalBuilding instanceof AnimalBuildingD){
changeButtonDisplay(btnAnimalBuildingD)
//Do something specific here
}
}
private void changeButtonDisplay(Button buttonToChange){
button.setVisible(true);
}
Where animalBuildings is a Set<AbstractAnimalBuilding> containing any combination of AnimalBuildingX's.
Assuming the structure at the top needs to be kept (eg, AnimalBuildingX HAS to extend AbstractAnimalBuilding), what would be a better approach than the multiple if-then-else statements in determining what kind of building animalBuilding is?
Would it feasible to simply create a new Interface as outlined in this question and have each AnimalBuildingX implement it while still extending AbstractAnimalBuilding or is there a way I can do it using the structure I currently have.
This is difficult to answer in general without more context.
One possibility is to create an abstract method in AbstractBuilding and implement it differently in the subclasses.
Another possibility is to use the visitor pattern.
It depends on the action you want to take on behalf of the derived class type. If an action has to be taken which can be perfomed without the need, that the calling class knows the concrete implementation of AnimalBuilding the interface method is appropriate. This usually is the case if you can find a common method description which is implemented differently for each concrete class (e.g. getName()).
If you need to do specific actions dependent on the concrete class (e.g. AnimalBuildingA differs from AnimalBuldingB), you can implement the visitor pattern:
public abstract class AbstractAnimalBuilding {
...
public abstract void accept(AnimalBuildingVisitor v);
}
public interface class AnimalBuildingVisitor<T> {
public T visit(AnimalBuildingA a);
public T visit(AnimalBuildingB b);
...
}
The implementation of the accept-method usually is the one liner
return v.visit(this);
Then you create an implementation of the Abstract visitor which does the work you want to perform in the loop. The loop then looks like this
ConcreteAnimalBuildingVisitor v;
for (AbstractAnimalBuilding animalBuilding: animalBuildings)
animalBuilding.accept(v);
This way, the concrete class "identifies" itself to the concrete visior which then can perform the appropriate action.
You can keep your current structure and achieve what you desire by using generics:
First we need to define a generic handler interface:
public interface AnimalBuildingHandler<T extends AbstractAnimalBuilding> {
void handle(T type);
}
And then, in your own custom class, we can implement specific function for each types:
/* Here you can define all */
public void handleAnimalBuildingA(AnimalBuildingA animalBuildingA) {
/**
* Implement your custom handling here
*/
System.out.println("Handling AnimalBuildingA" + animalBuildingA);
}
public void handleAnimalBuildingB(AnimalBuildingB animalBuildingB) {
/**
* Implement your custom handling here
*/
System.out.println("Handling AnimalBuildingA" + animalBuildingB);
}
And then, we can create a magic handler class that implements the above AnimalBuildingHandler interface by mapping handlers to types just like this:
private Map<Class<? extends AbstractAnimalBuilding>, AnimalBuildingHandler<? extends AbstractAnimalBuilding>> handlersMapping;
{ /* default instance initializer */
handlersMapping = new HashMap<>();
handlersMapping.put(AnimalBuildingA.class, new AnimalBuildingHandler<AnimalBuildingA>() {
#Override
public void handle(AnimalBuildingA type) {
handleAnimalBuildingA(type);
}
});
handlersMapping.put(AnimalBuildingB.class, new AnimalBuildingHandler<AnimalBuildingB>() {
#Override
public void handle(AnimalBuildingB type) {
handleAnimalBuildingB(type);
}
});
}
#Override
public void handle(AbstractAnimalBuilding type) {
AnimalBuildingHandler abh = handlersMapping.get(type.getClass());
abh.handle(type);
}
And finally, the test method:
public <T extends AbstractAnimalBuilding> void test() {
List<T> allAnimalBuildings = new ArrayList<>();
allAnimalBuildings.add((T) new AnimalBuildingA());
allAnimalBuildings.add((T) new AnimalBuildingB());
for (AbstractAnimalBuilding aab : allAnimalBuildings) {
handle(aab);
}
}

Is it not necessary to implement get method in class B ? Why compiler not enforcing ? Any concepts I missed?

interface A{
public void get();
public void set();
}
abstract class abstractA implements A{
#Override
public void get(){
System.out.println("in get funciton");
}
abstract public void set();
}
class B extends abstractA implements A{
#Override
public void set(){
System.out.println("In set method");
}
}
Is it not necessary to implement get method in class B?
Is it because abstractA already implemented the same method ?
Is this multiple inheritance ?
Is it not necessary to implement get method in class B?
No, since abstractA already implements it and B extends abstractA.
Is it because abstractA already implemented the same method ?
Yes. And because B extends abstractA. Both are required for this to work.
Is this multiple inheritance ?
No, it is not. B is still inheriting only one class - abstractA.
No because get() is already implemented in abstractA. This is inheritance.
Java does not allow multiple inheritance (which consist in inheriting from multiple classes BTW). The class B inherits from abstractA, and implements the behavior required by A. Actually, you could write your code like this :
interface A{
public void get();
public void set();
}
abstract class abstractA implements A{
#Override
public void get(){
System.out.println("in get funciton");
}
abstract public void set();
}
class B extends abstractA /* no need to specify that B implements A */{
#Override
public void set(){
System.out.println("In set method");
}
}
B inherits everything implemented by abstractA, which also include its interfaces.
B inherits the implementation of get() from abstractA.
Multiple inheritance is when B inherits from more than one classes. Which is not the case here.

difference between instantiation an interface or implementing an interface

what is the difference between creating an Object of interface and implementing an interface
example :
public interface A{
public void testMethod();
}
on way is creating an object of interface
public class B{
A a = new A(){
#override
public void testMethod(){ //implemtation here }
};
}
other way is
public class B implements A
{
#override
public void testMethod(){}
}
You are wrong:
here you anonymously implement interface and you alrady have instance of annonymouse class
public class B{
A a = new A(){
#override
public void testMethod(){ //implemtation here }
};
}
Here you create named implementation, you only create class without instantiate it.
public class B implements A
{
#override
public void testMethod(){}
}
You can't create an object of interface. Interface it's an abstract class but with all the methods are abstract. In the first code you are creating an anonymous class (i recommend you to read about this feature in java) that implements the interface A, in this case you are limited with the interface's methods even if you define additional method in your implementation you can't call it. In the second code you are creating a class that implements the interface A which means that you have a class that at least contain all the methods defined in the interface A and you can add inside your class B other methods and call its.

Enforcing instance variable implementation from an abstract class in Java

I am trying to design an abstract class which will enforce implementation of an instance variable even though the type if this instance variable is unknown at the abstract level. For example:
public abstract class AbstractDiet{
abstract void computeMeat()
abstract void computeVeggies()
…
}
public abstract class AbstractAnimal{
protected AbstractDiet diet;
…
}
Then I'd like users to implement something like:
public class Cat extends AbstractAnimal{
protected CatFoodDiet diet; // CatFoodDiet extends AbstractDiet
…
}
Is this the best way to implement the diet variable? I want to ENFORCE that a subclass of AbstractDiet is always implemented in a subclass of AbstractAnimal.
First of all: Keep your instance variables private, and provide accessor methods.
Second of all: It sounds like you are trying to define an interface. Use an interface any time you want to say something like, "every animal has a diet."
interface Animal {
Diet getDiet();
...
}
If you like, you can also incorporate Bohemian's idea, and make it generic.
interface Animal<D extends Diet> {
D getDiet();
...
}
That way, you will have maximum freedom when it comes time to define different kinds of animal
class Cat implements Animal<CatDiet> {
CatDiet getDiet() { return...; }
}
You can't (and shouldn't) approach the design like that. Using abstract classes, try something like this:
public abstract class AbstractDiet {
abstract void compute();
}
public abstract class AbstractAnimal<T extends AbstractDiet> {
protected T diet;
}
public class CatFoodDiet extends AbstractDiet {
compute() {
//
}
}
public class Cat extends AbstractAnimal<CatFoodDiet> {
// use field in super which is type CatFoodDiet
}
But typically you would use interfaces instead of abstract classes for the abstract types.
The most flexible way is to just require the subclass to provide the information:
public abstract class AbstractAnimal {
// Subclasses must provide a function that returns the diet
public abstract AbstractDiet getDiet();
}
public class PetRock extends AbstractAnimal {
#Override
public AbstractDiet getDiet() {
return new SunlightDiet();
}
}
If you want to force a particular implementation, this is a common way:
public abstract class AbstractAnimal {
private AbstractDiet diet;
// Provide a constructor that sets a diet
protected AbstractAnimal(AbstractDiet aDiet) {
if (null == aDiet)
throw new NullPointerException("Diet must be specified");
diet = aDiet;
}
public class PetRock extends AbstractAnimal {
public PetRock() {
// Subclasses have to provide a diet to the superclass
super(new SunlightDiet());
}
}

Categories