daveslab
daveslab

Reputation: 10310

How to set a variable type to be "something that implements these two interfaces"?

So, yes I've seen this question. However, what if I had two interfaces, IA and IB, but I wanted a parameter to a function (or property of a class) to be:

public void (<? extends IA, IB> someClass) {
//...
}

Is there a way to do this without using generics?

EDIT:

I've realized that what I really want is Duck Typing, like in Python. I just didn't get my words out right. With that in mind, clearly there is no real way to do this in Java. I accepted this answer, but then realized that the input would have to have the signature of that new interface to work. However, he did meet my awkwardly-worded criteria :).

Upvotes: 2

Views: 142

Answers (3)

emory
emory

Reputation: 10891

Extending CrazyJugglerDrummer's answer

interface IAandIB extends IA, IB { }


public void Foo(IA a , IB b )
{
     if ( a != b )
     {
         throw new IllegalArgumentException ( ) ;
     }
     ClassLoader loader = IAandIB . class . getClassLoader ( ) ;
     Class < ? > [ ] interfaces = new Class < ? > [ IAandIB . class , IA . class , IB . class ] ;
     InvocationHandler handler = new InvocationHandler ( )
     {
           public Object invoke ( Object proxy , Method method , Object [ ] args ) throws Exception
           {
                 Object r = null ;
                 try
                 {
                      // since a==b, it should not matter whether we use a or b here.
                      r = method . invoke ( a , args ) ;
                 }
                 catch ( InvocationTargetException cause )
                 {
                       throw cause . getCause ( ) ;
                 }
                 catch ( Exception cause )
                 {
                       throw new RuntimeException ( cause ) ;
                 }
           }
     }
     IAandIB ab = ( IAandIB ) ( Proxy . newProxyInstance ( loader , interfaces , handler ) ) ;
     Foo ( ab ) ;
}

public void Foo(IAandIB someClass) {
//...
}

Upvotes: 1

Gordon Gustafson
Gordon Gustafson

Reputation: 41209

interface IAandIB extends IA, IB { }

public void Foo(IAandIB someClass) {
//...
}

Since interfaces can extend multiple other interfaces, you can just make an empty 'dummy interface' that extends both of them, and use it as the type to designate whenever both are required.

This works, but is not a catch-all solution as it requires you to modify every single class that implements IA and IB so they can work for this method, which is annoying at best and impossible in some situations. Unfortunately, I do not know of any other way to do this without generics.

Upvotes: 5

Jesper
Jesper

Reputation: 206836

This syntax works for a method that you want to pass something into that implements two interfaces IA and IB:

public <T extends IA & IB> void someMethod(T arg) {
    // ...
}

For a member variable of a class:

public class Example<T extends IA & IB> {
    private T value;

    // ...
}

(Why do you want to do this without generics?).

Upvotes: 6

Related Questions