I have an abstract class A and several implementations of it. I expect this to evolve over time, by adding more implementations.
I also have an interface that does something at instances of the above class hierarchy (eg print them).
I want implementations of the interface to provide some special functionality for some of the subclasses of A and a default functionality for the rest of them.
I hope this example clarifies things:
abstract class A { }
class B extends A { }
class C extends A { }
interface Processor {
public void process(A a);
}
class SimpleProcessor implements Processor {
//I want this to be called when argument is instance of A or C or any
//new class that will be added in the future
public void process(A a) {
//Line 14
System.out.println("Default processing");
}
//I want this to be called when argument is instance of B
public void process(B b) {
System.out.println("Special processing");
}
}
public class Runner {
public static void main(String[] args) {
B b = new B();
Processor p = new SimpleProcessor();
p.process(b);
}
}
The example prints "Default processing". The problem is that the method to be executed is chosen based at the compile-time type of the interface's method. Is there a way (or design pattern) to make this program print "Special processing" without adding at line 14 a list of
if (a instance of B)
process( (B) a );
for every class that needs special processing?
I had a look at the visitor pattern but it doesn't seem like an improvement because I don't want to "pollute" the Processor interface with methods for every subclass of A because more subclasses of A will be added.
To put it another way, I want the implementations of the interface to:
Thanks!!
Move the code into the type which varies and use polymorphism. See Open Closed Principle.
interface Processable {
void process();
}
abstract class A implements Processable {
public void process() {
System.out.println("Default processing");
}
}
class B extends A {
public void process() {
System.out.println("Special processing");
}
}
class C extends A {
// default implementation inherited from A
}
class SimpleProcessor {
public void process(Processable p) {
p.process()
}
}
public class Runner {
public static void main(String[] args) {
B b = new B();
Processor p = new SimpleProcessor();
p.process(b);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With