3

I have multiple interfaces and a class that implements all of them. I want to call all the methods defined in these interfaces on an instance of the implementing class, but I don't want to declare the variable as of the class type so that I'm still programming to interfaces.

It seems that I have either to:

  1. Cast the object from one interface type to another to call the appropriate methods.
  2. Create a union interface which extends the others and declare a variable of that type.

I would prefer not to do either of these because 1 is not type-safe and 2 can mean you quickly end up with a lot of 'union' interfaces which add nothing in themselves. Is it possible to have something like:

public interface A {
    public void doThis();
}

public interface B {
    public void doThat();
}

public class C implements A, B {
    public void doThis(){;}
    public void doThat(){;}
}


//Fake calling code:
public void go() {
    A,B dualTypedInstance = new C(); //
    dualTypedInstance.doThis();
    dualTypedInstance.doThat();

}

It really seems like this should be possible. Thanks.

user1675642
  • 717
  • 1
  • 5
  • 13
  • What is the problem with approach 1 ? – NINCOMPOOP Apr 13 '13 at 08:56
  • read about _polymorphism_ – Juvanis Apr 13 '13 at 08:58
  • 1
    Yes, you described all possibilities. There is no Union-type in Java. Since interface cannot implement interfaces, you could only have a base class (abstract or not) and use it to be a combined type. You impl. then needs to extend it. – eckes Aug 10 '14 at 00:50
  • Found a similar question with more answers here: https://stackoverflow.com/questions/48143268/java-tagged-union-sum-types – Liutong Chen Jul 03 '19 at 17:29

6 Answers6

2

You can do this:

ImplementsInterfaces impl = new ImplementsInterfaces();
A a = impl;
B b = impl;
allyourcode
  • 19,438
  • 17
  • 73
  • 100
1

it's not completely impossible to do this in 2019, though I wouldn't necessarily recommend the solution in production code, and it also carries the caveat that the object has to be immutable. For example, to create a class that effectively has an instance variable that implements InterfaceA and InterfaceB, which have methods methodA() and methodB(), respectively, you can do something like

public interface MyInterface {
  public void methodA();
  public void methodB();

  public static <O extends InterfaceA & InterfaceB> MyInterface of(O obj){
      return new MyInterface(){
          public void methodA(){
               obj.methodA();
          }

          public void methodB(){
               obj.methodB();
          }
      };
  }

This creates an anonymous inner class that effectively has a final instance variable of types InterfaceA and InterfaceB, without demanding any particular implementation of that dependency.

0

Why don't you want to instantiate the class (c) that implements (a) and (b)?

Another way you could to this is to create abstract classes out of (a) and (b), and have two abstract methods (one in each as you already have), then you create the class (c) which then extends (instead of implements) the other classes.

Arash Saidi
  • 2,150
  • 17
  • 31
0

One alternative is the creation of a abstract super class:

public abstract class AbstractAB implements A, B {
}

public class C extends AbstractAB {
    public void doThis(){;}
    public void doThat(){;}

}

public void go() {
    AbstractAB dualTypedInstance = new C();
    dualTypedInstance.doThis();
    dualTypedInstance.doThat();
}
Eduardo Leggiero
  • 617
  • 1
  • 8
  • 28
0

You also can do this in the Class declaration:

public class<T extends A & B> SomeClass{
     Void doStuff(){
          T variable = new C();
     }
}
Dharman
  • 21,838
  • 18
  • 57
  • 107
-1

Interfaces should contain a distinct abstraction unit, so that they can be used separately, i.e. without knowledge of their implementation and without dependence on other interfaces that could possibly be implemented in a class. Interfaces can extend other interfaces, but the hierarchy is not a thing in itself, it is something that should have some meaning within your application. So, if you are forced to make many artificial 'marker' interfaces, the odds are quite high that you are doing something wrong. Last but not least, you can have an abstract base class that can implement the necessary interfaces.

Let me illustrate this with a simple example. Suppose you are creating a frond-end for an application. You can think of different panels that can be draggable, or realizable. Putting it in java terms, there can be two interfaces: Draggable with a drag() method and Resizable with redize() method. Under a drag event your API shouldn't be aware of the implementating class details, the only thing it should care of is, does this class implement Draggable, or not. But it you'd like to have a concrete implementation that has both interfaces implemented in a possibly different ways, you can create an abstract class as A basis for concrete implementations: abstract class BasePanel extends Panel implements Draggable, Resizable. This way, you declaed your class in a way that would be hsed in a separate 'drag' a d 'resize' context. On the other hand, if you wanted to have a context that would be aware of them both you could create another interface that extends both basic interfaces and possibly adds another methods like public interface GuiUnit extends Draggable, Resizable.

Finally, my idea was to show you that you should avoid design situations when you expect conditional casting between unrelated interfaces and either base your implementations on exactly one interface that you expect to deal with, or on some set of abstract classes. If you think that it's not enough - you'd be better off rethinking your design considerations.

skuntsel
  • 11,346
  • 11
  • 41
  • 64