0

I got a class which uses a Proxy. It looks something like this:

public class BarWrapper
{
    private final Bar bar;

    public BarWrapper(Bar bar)
    {
        this.bar = bar;
    }

    public int someMethodInBar()
    {
        return bar.someMethodInBar();
    }

    public int someMethodInBar2()
    {
        return bar.someMethodInBar2();
    }

    public int someMethodInBar3()
    {
        return bar.someMethodInBar3();
    }


    // etc
}

The Bar is some super class and the dynamic type will be a derivative.

I got an interface and I want the wrapper to implement that interface and keep using the proxy with the same methods, but Bar itself doesn't implement that interface and I don't have any access to it. How can I force the user to pass a dynamic type that is not only a derivative of Bar but also implements the interface so I will have no problem doing this:

(Iinterface)bar.interfaceMethod();
CodeMonkey
  • 11,196
  • 30
  • 112
  • 203
  • `if (!bar instanceof Iinterface) throw new IllegalArgumentException()`? – Dorus Jun 21 '15 at 16:10
  • I prefer to find a way to force it on compilation time – CodeMonkey Jun 21 '15 at 16:10
  • How about changing the constructor to `public BarWrapper(Iinterface bar) [...]`. If you do use any of the methods that are in `Bar` but not in `Iinterface`, i suggest you add these to `Iinterface` (perhapts extend the interface into a `IinterfaceBar`). – Dorus Jun 21 '15 at 16:13
  • one way that I can see is to use reflection to see if the object implements the interface and throw an exception if it doesn't. Edit - beat to it. – Ron Thompson Jun 21 '15 at 16:14
  • @RonThompson Please read the first two comments. – Dorus Jun 21 '15 at 16:14

2 Answers2

2

If you need the wrapped object to be both a subclass of Bar and an instance of the interface Foo, that Bar doesn't implement, then the only way I see is to accept a subclass of Bar that implements Foo:

public abstract FooBar extends Bar implements Foo {
}

That will do what you want: the user will be forced to extend FooBar, and thus to provide a subclass of Bar that implements Foo.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
1

Instead of taking the object Bar, only accept the interface.

private final Iinterface bar;
public BarWrapper(Iinterface bar)
{
    this.bar = bar;
}

That does require your proxy to only call methods in the interface. It is possible you also want to call methods that are in Bar, but not Iinterface. The only way to enforce that at compile time, is to add these methods to the interface, perhaps extend the interface:

public interface IinterfaceBarWrapper implements Iinterface
{
    public void someMethodInBar();
    public void someMethodInBar2();
    public void someMethodInBar3();
}

...

private final IinterfaceBarWrapper bar;
public BarWrapper(IinterfaceBarWrapper bar)
{
    this.bar = bar;
}
Dorus
  • 7,276
  • 1
  • 30
  • 36
  • That won't force the use to extend Bar though. You can implement IinterfaceBarWrapper without extending Bar at all. But I agree that this is the cleanest OO way. The wrapper shouldn't care whether the interface methods are implemented by extending Bar or not. – JB Nizet Jun 21 '15 at 16:21
  • @JBNizet You already covered that with your answer, I didn't feel like duplicating what was already stated. I can think of three solutions here: Throw a exception at runtime, add a abstract class that extend bar and the interface, or extend the interface (if you use non-interface methods at least, else just use the interface directly). They all have there own merits and demerits. – Dorus Jun 21 '15 at 16:47