Одной альтернативой является перемещение полиморфного поведения в реализации BaseType
, а не в реализации BaseCalculator
.Например:
public interface BaseType {
public void process(Calculator calc);
}
public class DerivedType1 implements BaseType {
@Override
public void process(Calculator calc) {
// Do something specific to derived type 1
}
}
public class DerivedType2 implements BaseType {
@Override
public void process(Calculator calc) {
// Do something specific to derived type 2
}
}
public class Calculator {
public void doSomething(BaseType bt) {
bt.process(this);
}
}
Если такого типа решения недостаточно, более сложным решением является Шаблон посетителя .Шаблон посетителя позволяет обрабатывать любой произвольный объект BaseType
любым произвольным BaseCalculator
с использованием double-dispatch .Уловка в том, что все реализации BaseCalculator
должны иметь метод для обработки каждой из реализаций BaseType
.Например:
public interface BaseType {
public void process(Calculator calc);
}
public class DerivedType1 implements BaseType {
@Override
public void process(Calculator calc) {
// Do something specific to derived type 1
}
}
public class DerivedType2 implements BaseType {
@Override
public void process(Calculator calc) {
// Do something specific to derived type 2
}
}
public interface BaseCalculator {
public void handle(DerivedType1 dt);
public void handle(DerivedType2 dt);
}
public class DerviedCalculator1 implements BaseCalculator {
@Override
public void handle(DerivedType1 dt) {
dt.process(this);
}
@Override
public void handle(DerivedType2 dt) {
dt.process(this);
}
}
public class DerviedCalculator2 implements BaseCalculator {
@Override
public void handle(DerivedType1 dt) {
dt.process(this);
}
@Override
public void handle(DerivedType2 dt) {
dt.process(this);
}
}