1

I am refactoring code... Considering this chain of inheritance...

public class Base

public class Simple extends Base

public class Secure extends Simple

public class Framework extends Secure

public class Application extends Framework

and the class

public class ApplicationCallback

Currently, ApplicationCallback has this method public abstract ApplicationCallback#doSomething(Application app), but I want it to be accessible by Base.... without changing the code everywhere from ApplicationCallback#doSomething(Application app) to ApplicationCallback#doSomething(Base base).

Is there a way I can define a method that I can define to prevent the code change everywhere?

Kind of like ApplicationCallback#doSomething(T<? extends Base> app), so that when overriding, I can just put ApplicationCallback#doSomething(Base base) and ApplicationCallback#doSomething(Simple simple) etc etc.

The question is about @Override ApplicationCallback#doSomething()

6
  • That looks like an awefully deep inheritance hierarchy, I doubt that's a good idea. Also, it's not clear to me what you mean by "accessible by Base". Commented Apr 20, 2018 at 14:22
  • 3
    "without changing the code everywhere from ApplicationCallback#doSomething(Application app) to ApplicationCallback#doSomething(Base base)" - You wouldn't have to change the calling sides since you widen the parameter type from Application to Base. Commented Apr 20, 2018 at 14:23
  • @Turing85 When using @Override, it would have to be changed to ApplicationCallback#doSomething(Base base). Is there a way to make it generic so that anything that extends Base is acceptable in the method input? Commented Apr 20, 2018 at 14:25
  • as @Turing85 said if you change the definition to doSomething(Base base) it will work for anything that extends Base. However if you want to strongly type doSomething you need to add a generic to the class definition. ApplicationCallback<T extends Base> { doSomething(T base)} Commented Apr 20, 2018 at 14:28
  • No. I am trying to override ApplicationCallback Commented Apr 20, 2018 at 14:31

1 Answer 1

1

You should introduce a generic parameter on the ApplicationCallback class. That allows you to define callbacks that take only certain subtypes:

class Callback<T extends Base> { abstract void doSomething(T t); }

That would allow you to use methods from the subtype you defined, for example if the Secure class adds a getSecureThing() feature, you could:

Callback<Base> base = new Callback<Base>() { 
  void doSomething(Base base) {
    // getSecureThing not available
  }
}
Callback<Application> app = new Callback<Application>() { 
  void doSomething(Application app) {
    // app.getSecureThing is available
  }
}
Sign up to request clarification or add additional context in comments.

8 Comments

This does require you to change all Callback implementations. If you're using IntelliJ, it has a feature called 'introduce type parameter' that will help you do that automatically.
If you need the generic parameter only on the doSomething(...)-method, only set this method generic: public <T extends Base> abstract void doSomething(T t);
That won't work. Try to implement it and actually call the callbacks - you'll see why.
Then my testcase seems to be missing something. It compiles and runs for me. Could you give me a hint?
@Turing85 Try to call the getSecureThing method from my example in a callback. It won't be available, because you can't force the callback implementation to only take Secure instances.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.