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 { public void consume(Tomato t) { ..... } } public static class AppleConsumer implements Consumer { public void consume(Apple a) { ..... } } } If creating these static inner classes bothers you, you can use anonymous classes: public class TwoTypesConsumer { private Consumer tomatoConsumer = new Consumer() { public void consume(Tomato t) { } }; private Consumer appleConsumer = new Consumer() { public void consume(Apple a) { } }; public void consume(Tomato t) { tomatoConsumer.
Consume(t); } public void consume(Apple a) { appleConsumer. Consume(a); } }.
1 +1 - This I rather like. – banjollity Aug 19 '09 at 7:56 somehow that looks tome like code duplication... I encountered the same problem and found no other solution that looks clean. – bln-tom Jun 9 at 19:42.
Because of type erasure you can't implement the same interface twice (with different type parameters).
1 I can see how it's a problem... the question is then what's the best (most efficient, safe, elegant) way to bypass this problem. – Daphna Shezaf Aug 19 '09 at 8:59 Without going into the business logic, something here 'smells' like the Visitor pattern. – Shimi Bandiel Aug 19 '09 at 9:27.
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 being an ancestor of Tomato and Apple.
Thanks, but whatever the pros says, I don't regard Tomato as fruit. Unfortunately there's no common base class other than Object. – Daphna Shezaf Aug 19 '09 at 7:46 You can always create a base class called: AppleOrTomato ;) – Shimi Bandiel Aug 19 '09 at 8:24 Better, add a Fruit that delegates to either Apple or Tomato.
– Tom Hawtin - tackline Aug 19 '09 at 16:40 @Tom: Unless i'm misunderstanding what you're saying, your suggestion only pushes the problem forward, since, for Fruit to be able to delegate to either Apple or Tomato, Fruit must have a field of a superclass to both Apple and Tomato referring to the object it delegates to. – Buhb Aug 19 '09 at 18:03.
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 getTomatoConsumer () { return new Consumer() { public void consume(Tomato t) { consumeTomato(t); } } public Consumer getAppleConsumer () { return new Consumer() { public void consume(Apple a) { consumeApple(t); } } } The implicit requirement of the question was Consumer and Consumer objects that share state. The need for Consumer,Consumer 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.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.