I have an interface with 1 method signature:
public interface UrlProvider {
String getUrl();
}
There are 2 implementations of this interface, and one of them has a public method whose signature is not in the interface because it only makes sense to be inside the implementation:
public class UrlProviderImpl implements UrlProvider {
@Override
public String getUrl() {
//implementation
}
public String getUrlAndAppend() {
//implementation
}
}
There's a third class that's going to have a UrlProvider field and Spring is going to handle the dependency injection and instantiating the correct beans. Is it possible to call getUrlAndAppend() on the interface level without explicitly instantiating the implementation?
This is what I am trying to achieve:
public class ThirdClass {
private final UrlProvider urlProvider;
public void myMethod() {
urlProvider.getUrlAndAppend();
}
}
In terms of design, how this is usually handled?
CodePudding user response:
If you know when you want the extra functionality in some places, consider making a new interface, or injecting the specific implementation in the places you know you need the extra functionality. Without reflection (which is a terrible idea; don't do it), you can't access that method from the interface.
public interface AppendingUrlProvider extends UrlProvider {
String getUrlAndAppend();
}
public class AppendingUrlProviderImpl implements AppendingUrlProvider {
@Override
public String getUrl() {
// implementation
}
@Override
public String getUrlAndAppend() {
// implementation
}
}
////
// Or modify your existing ThirdClass
////
public class ThirdClass {
// inject the implementation, not the interface
private final UrlProviderImpl urlProvider;
public void myMethod() {
urlProvider.getUrlAndAppend();
}
}
Solutions aside, the first thing you should really do is figure out exactly why you need this extra public method on just one of the implementations. Is this something that callers should be doing instead of the implementation? Should this be on the interface? Is this only needed for testing? Only you can answer this, but it's worth taking a step back to make sure you've set up your codebase for success and longterm maintainability.
CodePudding user response:
Did you try your own code?
You can't call a method that belongs to an instance of a class, if you do not instantiate that class.
In your example, if you call myMethod without instantiating UrlProvider
you will get a NullPtrException.
If you want to have access to getUrlAndAppend
from the interface, you will need to declare that method as "default"
in the interface itself or as Static
from the implementation (and that way you do not need to instantiate it to call the method), but I'm having trouble to understand what you want to achieve from this.