0

Possible Duplicate:
Java method overloading + double dispatch

probably a dumb newbie question:. I want to avoid instanceof operator in situations like this:

class Service {
  method(Some param) {  }
}

class Special extends Some { }

class SpecialService extends Service {
  method(Some param) {
    if (param instanceof Special) {
      //do special things 
    }
  }

  method(Special param) {
    //do special things 
  }

}

Is the second special method the correct way to avoid the instanceof ?

Will there be any problems on the caller side of the service? In my case the special service is a customized version, plugged in and called from base code. Which method will be called?

Service s = new SpecialService();
s.method(specialparam);

And please point me to compact description or pattern how to solve this. Seems to be basic Java / OO knowledge...

Community
  • 1
  • 1
Bastl
  • 2,926
  • 5
  • 27
  • 48
  • `Service` knows nothing about `SpecialService`. What are the `special things` that you need to do? – Andrew Logvinov Dec 07 '12 at 16:41
  • Yes, it is going to work based on the runtime type, so you are OK. It's a duplicate, though. – Sergey Kalinichenko Dec 07 '12 at 16:41
  • The method will be chosen based on the runtime type of the receiver (`Service` vs `SpecialService`) but the compile-time type of the arguments (`Some` vs `Special`). So, if you do `Some some = new Special(); Service service = new SpecialService(); service.method(some);` then the first method in `SpecialService` will be called. – Tom Anderson Dec 07 '12 at 17:23
  • I think it's best to avoid editing the automatically-inserted "duplicate" text block; use comments or chat or meta instead, or just edit the body of the post. – Oak Dec 10 '12 at 09:25

2 Answers2

0

Java does this automagically. Your code will work exactly as you want to, without the if statement. Java selects the most specific (most subclassed) method signature when choosing which version of the method to execute.

Here is a really good article on the subject.

durron597
  • 31,968
  • 17
  • 99
  • 158
0

I'm not sure durron597 is right. It all depends on how your code is written. It would workautomatically only if both variables are declared using specific types:

//good
Special specialparam = new Special();
SpecialService s = new SpecialService();
s.method(specialparam);

Code like

//bad
Some specialparam = new Special();
SpecialService s = new SpecialService();
s.method(specialparam);

or like

//bad
Special specialparam = new Special();
Service s = new SpecialService();
s.method(specialparam);

wouldn't work as you expect because known compile-time types are used to select method.

The whole design looks suspicously. This might be the right way but probably it is worths reconsidering it.

One of things that might hepl is Double dispatch mentioned by dasblinkenlight's comment. But to do one of base classes (Some or Service) should know about special cases. In short idea is that you write something like this:

class Some {
  public void dispatch(Service service)  {
    service.method(this);
  }
}

class Special extends Some { 
  public void dispatch(Service service)  {
    service.method(this);
  }
}



class Service {
  void dispatch(Some some) {
      some.dispatch(this);
  }


  void method(Some some) {
     // do common things here  
  }

  void method(Special some) {
     method((Some)some);
  }
}

class SpecialService extends Service {

  method(Special param) {
    //do special things 
  }
}
SergGr
  • 23,570
  • 2
  • 30
  • 51