Can interface methods be overloaded? - java

I'm trying to achieve an overloaded interface method. I know that this does not work in Java, but how could I rewrite the following to have the implementation type in my action() methods, and not the Base type?
class Base;
class Foo extends Base;
class Bar extends Base;
interface IService {
void action(Base base);
}
class FooService implements IService {
void action(Foo foo) {
//executes specific foo action
}
}
class BarService implements IService {
void action(Bar bar) {
//executes specific Bar action
}
}
usage:
Base base; //may be foo or bar
anyService.action(bar);
You get the idea. How could I do this?

Define an interface that both Foo and Bar should implement, so you can do like:
interface Actionable{
public void action;
}
class Base;
class Foo extends Base implements Actionable;
class Bar extends Base implements Actionable;
interface IService {
void action(Actionable a);
}
class FooService implements IService {
void action(Actionable a) {
...
}
}
class BarService implements IService {
void action(Actionable a) {
...
}
}
Anyway interfaces should make your code more robust and reusable - if you are looking into hacks to make them work, consider designing your application better.

This is not supported in Java and you are violating the OOP rules.

Depending on your intended usage, there are multiple things to try.
If your calls to the IService know which kinds of object they can take, you could try generics.
interface IService<T extends Base> {
void action(T foo)
}
and usage:
IService<Foo> fooService = ...
fooService.action(fooObject);
If that's not the case, you could have some check in your ´Base´ class to allow differentiation for your IService interface.
class Base {
boolean acceptsFoo();
boolean acceptsBar();
}
and you could use it like:
class AnyService implements IService {
void action(Base base) {
if (base.acceptsFoo()) {
((FooService) base).foo();
}
}
However, this seems like a strange design. An interface is aimed at providing uniform access, and if you need to differentiate between the arguments, this is almost always a sign of an interface that can be split up into several parts...

You can always typecast to a specific type to execute that action.
void action(Base base)
{
if(base instanceof Foo)
{
Foo foo = (Foo) base;
//executes specific foo action
}
else
{
// handle the edge case where the wrong type was sent to you
}
}

any way if you are passing objects of sub class
then behavior (instance methods) will be called of object(subclass) passed(polymorphism)
ie.overloaded method

Related

How could I call an abstract class method who is common between subclasses without instanciating any subclass

I have a code like this :
interface Contract {
createSomething(); //not common
updateSomething(); //not common
getSomething(); //method who is supposed to be common between all strategies
}
interface Strategy {
createSomething();
updateSomething();
getSomething();
}
Abstract class AbstractStrategy implements Strategy {
#Override
getSomething() {
// the common code
}
}
class strategyA extends AbstractStrategy {
#Override
createSomething() {...}
#Override
updateSomething() {...}
}
class ContractImpl implements Contract {
#Override
createSomething() {
//get the good strategy
//call the strategy.createSomething();
}
#Override
updateSomething() {
//get the good strategy
//call the strategy.updateSomething();
}
#Override
getSomething() {
**Here is the question**
}
}
Question:
How could I rewrite this code so I could call the getSomething() method without having to instanciate a random subclass just to call it with the super keyword ?
You can't. Rather, you could extract the code into a static method and subsequently call it from getSomething(). This would allow you to call it statically when you need to, and from an instance when needed as well.
In other words, your AbstractStrategy class should look like:
Abstract class AbstractStrategy implements Strategy {
public static void sharedCode(parameters needed) {
// the common code
}
#Override
(signature) getSomething() {
sharedCode(this.parametersNeeded);
}
}
You basically can't. An abstract class can't be instantiated, so you can't call an instance method without having an object of a concrete implementation (in your case any concrete subclass of AbstractStrategy).
One option that you have is to create an anonymous class so that you can call the method without instantiating any of your subclasses of AbstractStrategy:
AbstractStrategy strategy = new AbstractStrategy() {
#Override
createSomething() {...}
#Override
updateSomething() {...}
}
strategy.getSomething();
But this feels hacky.

Does java support "Soft" interfaces?

Consider the following scenario:
Say that you created an interface Foo:
public interface Foo {
public void bar();
}
And say that there is an old class SomeOldClass in a certain library that you want to use. It already has the bar() method, but does not explicitly implement Foo.
You have written the following code for all classed that implement Foo:
public <T extends Foo> T callBarOnThird(List<T> fooList){
return fooList.get(2).bar();
}
And now you want it to also work for SomeOldClass. You dont have access to the source code of this class, so you can't modify it.
Is there a way to declare Foo or something similar as some sort of "soft" interface, (as in where any class that implements all the required methods would be accepted as an implicit implementation of the soft interface)? If not, how would you solve this with code that is as clean as possible?
No, it does not.
You have to provide an adapter instance (there are several methods and tools to help with that, but Java does not do it "implicitly").
Java is statically typed and dynamically bind.
Dynamically bind: This means that the linking between a method signature and its implementation happens at runtime. For example.
For example
public interface MyInterface {
void doStuff();
}
public class MyFirstImpl implements MyInterface {
#Override
public void doStuff() {
// do some stuff here
}
}
public class MySecondImpl implements MyInterface {
#Override
public void doStuff() {
// do some stuff here
}
}
So if you would have the next snippet
MyInterface test; // pointing to either MyFirstImpl or MySecondImpl
test.doStuff();
The JVM will determine at runtime weather to call the doStuff method from MyFirstImpl or MySecondImpl based on the runtime type of the object.
Statically typed: This means that the JVM will check at compile time weather a there is a method to call regardless of the implementation.
For example:
public interface MyInterface {
void doStuff();
}
public class MyFirstImpl implements MyInterface {
// no override here
public void doStuff() {
// do some stuff here
}
}
public class MySecondImpl implements MyInterface {
// no override here
public void doStuff() {
// do some stuff here
}
}
So if you would have the next snippet
MyInterface test; // pointing to either MyFirstImpl or MySecondImpl
test.doStuff();
The compiler will complain because it can't ensure at compile time that regardless of the implementation of MyInterface there is a doStuff method to call (although in this case, both implementations of MyInterface define a doStuff method).
This ensures that you won't get a NoSuchMethodException at runtime, if you would pass, for example, the next implementation.
public class MySecondImpl implements MyInterface {
// no override here
// no doStuff method
}
This adds some type safety to the language at the cost of some rigidity (since you are able to determine the issue earlier than at runtime and therefore you have a shorter feedback loop, at the cost of the scenario in which all the implementations actually expose the method not working out of the box).
How you should refactor your code:
Create a wrapper over the third party library and expose the interface from the wrapper.
public interface Foo {
void bar();
}
public class ThirdPartyFooWrapper implements Foo {
private SomeOldClass oldClass;
public ThordPartyFooWrapper (SomeOldClass oldClass){
this.oldClass = oldClass;
}
#Override
public void bar() {
this.oldClass.bar();
}
}
Then, in your code use ThirdPartyFooWrapper instead of SomeOldClass.
Hope this answers your question!
Extension to Thilos answer.
You can also use the decorator to handle this
public <T extends Foo> T callBarOnThird(List<T> fooList){
return new BarDecorator(fooList.get(2)).bar();
}
Inside the decorator, you can check if given Object is the instance of Foo or not then do operations accordingly.

Java - OOP - enforce specific implementation during compile time

My code has a set of "factories" (IfaceProducerProcessor) producing different inner implementations of the same interface (Iface). Those factories should also be able to later perform some processing on an instance they produced, but not on other implementations of Iface.
Needless to say, the calling code should not be aware of the implementation details or inner interfaces of specific Iface instance, only that it should pass it to its original producer alone for processing.
How can I enforce that only the same concrete class be passed to the class that produced it? Generics maybe?
interface Iface {
void foo();
}
interface IfaceProducerProcessor {
Iface produceIface();
void processIface(Iface iface);
}
class A implements IfaceProducerProcessor {
Iface produceIface() {
return new AIfaceImpl();
}
void processIface(Iface iface) {
// How to enforce AIfaceImpl in compile-time?
if (!(iface instanceof AIfaceImpl)) {
throw IlleagalArgumentException("Expected instanceof AIfaceImpl.");
}
...
((AIfaceImpl)iface).bar();
...
}
class AIfaceImpl implements Iface {
// implementation of foo() ...
void bar() {
}
}
}
class B implements IfaceProducerProcessor {
...
class BIfaceImpl implements Iface {
...
}
}
...
If it is obvious that I have a design flaw I will be happy to hear what it is and how to correct it, but bear in mind this is a simplified example of my code, and the specific details I can't get into led me to the given design...
Your guess with the generics may work the best, consider following change to the IfaceProducerProcessor. Note the generic parameter I which is boundet to be an implementation of Iface only:
interface IfaceProducerProcessor<I extends Iface> {
I produceIface();
void processIface(I iface);
}
Which then the class A implements with the following definition:
class A implements IfaceProducerProcessor<AIfaceImpl>{
public AIfaceImpl produceIface(){
/* ... */
}
public void processIface(AIfaceImpl iface){
/* ... */
}
}
That way you're enforcing via the compiler that you only want to use AIfaceImpl in this specific IfaceProducerProcessor.
The same can then be done for every implementation of IfaceProducerProcessor:
class B implements IfaceProducerProcessor<BIfaceImpl>{
/* ... */
}
And so on.

How to return type Interface

I am currently working on a project with a Binary tree and code for printing out a tree has been obtained from a repository.
Long story short it will printout in my desired format if I can implement an interface in my code.
However one of these requires an unusual return of an interface class. (see below)
#Override
public IBT getLeft() {
return null;
}
This is the method for getting the left subtree where IBT is the Binary tree interface.
Is this simpler than I am making it?
Any help in returning Interfaces?
The method getLeft can return any class which implements IBT (if it is an interface) or extends IBT (if it is a class).
For example. Say I have the interface Foo, and two implementations, Fizz and Buzz:
public interface Foo { }
public class Fizz implements Foo {}
public class Buzz implements Foo {}
The Fizz and Buzz class can now be used in place of Foo because they implement the Foo interface.
Now say I have a method which requires I return Foo objects.
public interface Bar {
Foo getFoo();
Foo getAnotherFoo();
}
You can't directly create a Foo object because it is not a class. You can however use the Fizz and Buzz classes instead.
public class BarImpl implements Bar {
#Override
public Foo getFoo() {
return new Fizz();
}
#Override
public Foo getAnotherFoo() {
return new Buzz();
}
}
interface Foo{void display();}
public class TestFoo implements Foo
{void display(){System.out.println(“Hello World”);}
public static void main(String[] args){Foo foo = new TestFoo();foo.display();}}
I think this is helpful.

How to pick action to execute based on objects instanceof?

I have some Implementations of class Base, and all objects are collected in a List<Base>.
How can I call a specific action based on the instanceof these objects, without having to use verbose instanceof checks? How could I pick a servicemethod to be executed based on the instance of these objects, but without having to care which object the action is executed on. The right service-method should be picked somehow automatically without typecasing or instanceof checks.
class Base;
class Foo extends Base;
class Bar extends Base;
class Service {
List<Base> bases;
public void someMethod() {
for (Base base : bases) {
//perform some instanceof dependend action.
//these actions cannot be inside of any Base class as it makes use of other objects too.
if (base instanceof Foo) {
fooService.action((Foo) base);
}
if (base instanceof Bar) {
barService.action((Bar) base);
}
}
}
}
//custom service methods
class FooService {
void action(Foo foo) {
}
}
class BarService {
void action(Bar bar) {
}
}
Polymorphism is one possibility. If the Base class contains an abstract action() method, you could call it directly, without any if statements.
Another is a registry. For each subclass of Base you could register a mapping to a service class. In someMethod(), look up the class in the registry, get the corresponding service class, and call it.
By the way, verbosity is not the only problem with the instanceof statements. Code you write with these can break as soon as a new subclass of Base is created. Satisfying the Open/Closed principle can result in less fragile code.
One possible solution is to use the Visitor pattern. You will need to combine FooService and BarService into a single class with both overloaded action() methods. Then you need to add a accept() method to each of the Foo and Bar classes which then can call the appropriate action() method. For more details see http://en.wikipedia.org/wiki/Visitor_pattern.
There are possibly other, more appropriate design patterns which can solve this problem. I suggest you study up on them.
The closest I ever got to solve this problem is:
class Base{};
class Foo extends Base{};
class Boo extends Base{};
Additional BaseService interface so every service class use the same methods:
public interface BaseService<T extends Base> {
void action(T base);
}
BooService:
public class BooService implements BaseService<Boo> {
public void action(Boo boo){
System.out.println("Action performed by BooService");
}
}
FooService:
public class FooService implements BaseService<Foo> {
public void action(Foo foo){
System.out.println("Action performed by FooService");
}
}
Additional ServiceSupplier class that will invoke proper Service base on passed object:
public class ServiceSupplier {
private Map<Class<? extends Base>, BaseService> services;
public ServiceSupplier(){
initializeServiceMap();
}
public BaseService getServiceOfType(Class<? extends Base> clazz){
return services.get(clazz);
}
private void initializeServiceMap() {
services = new HashMap<>();
services.put(Foo.class, new FooService());
services.put(Boo.class, new BooService());
}
}
And your Service class:
public class Service {
List<Base> bases;
ServiceSupplier serviceSupplier;
public Service(){
serviceSupplier = new ServiceSupplier();
bases = new ArrayList<>(Arrays.asList(new Foo(), new Boo()));
}
public void someMethod() {
bases.forEach(base -> serviceSupplier.getServiceOfType(base.getClass()).action(base));
}
}
May seem much as just for removing few "if" statements but having more services all you need to do is add them to initializeServiceMap() method.

Categories

Resources