4

here is my scenario:

class SomeBaseClass
{
     public void foo(String str)
     {
     .......
     }
     public void foo(String strs[])
     {
     .......
     }
}

class MyClass extends SomeBaseClass
{
     public void foo(String str)
     {
           super.foo(str);
     }
     public void foo(String strs[])
     {
           throw new RuntimeException("only one input please!");
     }
}

The logic is pretty simple. "SomeBaseClass" is 3rd party tool that i cannot modify. I want to limit its functionality and don't want to allow foo(String strs[]).

the problem is that inside SomeBaseClass foo(Sting str) internally calls foo(String strs[]). Hence when i call foo(String str) of MyClass, I get a runtime exception. How can I tell the SomeBaseClassclass to use SomeBaseClass::foo(String strs[]) and all other classes to use MyClass ::foo(String strs[])

PC.
  • 6,870
  • 5
  • 36
  • 71

2 Answers2

5

Consider writing a wrapper

class MyClass extends SomeBaseClass
{
    private SomeBaseClass impl = new SomeBaseClass ();

    public void foo(String str)
    {
        impl.foo(str);
    }

    public void foo(String strs[])
    {
        throw new RuntimeException("only one input please!");
    }
}
Andrei LED
  • 2,560
  • 17
  • 21
  • 3
    I think it ought to be pointed out that *every single method* inherited from `SomeBaseClass` will have to be forwarded to `impl`, and if `SomeBaseClass`'s vendor decides to quietly add a new member function in a new version, this'll quietly break. – NPE Sep 22 '11 at 19:51
  • 1
    Am I missing something here? `MyClass` still `extends SomeBaseClass`, so how exactly is it this stopped: `MyClass.foo(String)`->`SomeBaseClass.foog(String)`->`MyClass.foo(String[])`->`throw ...`. Got it. :) – Kashyap Sep 22 '11 at 19:57
  • Here `impl.foo(str)` impl is an instance of `SomeBaseClass` so it will not lead to `MyClass.foo (String[])`. – Andrei LED Sep 22 '11 at 20:01
  • 2
    in my original implementation, SomeBaseClass has like 100's of methods and properties. its completely bad practice to make such an implementation as there will a lot of maintenance / up-gradation issues. – PC. Sep 27 '11 at 05:31
2

Perhaps over engg but inside MyClass.foo(String strs[]) you can check if the caller is SomeBaseClass.foo(String str), if yes, let the call go thru to super.foo(String) else throw RuntimeException.

To find the caller check StackTrace.

Kashyap
  • 15,354
  • 13
  • 64
  • 103
  • 2
    Using stack trace may decrease performance significantly, though there's another way to determine whether to call super or throw an error. In `foo (String)` you can mark that super call is allowed (using local class variable if thread-safety isn't required or using ThreadLocal otherwise) and check the flag in `foo (String[])`. But wrapper is a better practice and in case of thread-safety will surely work faster. – Andrei LED Sep 22 '11 at 19:56
  • Good point (abt the flag), guess it's the best option, (you should add it). It's also possible to make it thread safe of course (with a little effort). I do agree abt the performance hit otherwise, but I took it that its implicit/clear. – Kashyap Sep 22 '11 at 20:01
  • 1
    both stacktrace and using flag worked. thanks Kashyap. I preferred using stack trace. – PC. Sep 27 '11 at 05:38
  • Great! Do note that even in my opinion Andrei's soln is better than mine. **I mean the one with teh flag**. But whatever sails ur boat. :) – Kashyap Sep 27 '11 at 16:59
  • 1
    @kashyap: i do agree its useful for some cases. but it my case the architecture is multi-multi threaded. i cannot risk thread-safety. – PC. Sep 30 '11 at 18:31