mardi 15 octobre 2019

Can you cast an object to an interface it doesn't explicitly implement?

I'm specifically interested in implementing a Strategy pattern where one (or more) of the strategies come from a third-party library.

I have a third-party library with a class like so:

public class LibraryClass {
    public void doSomething() {
        // ...
    }
}

I then created my own class with the same interface:

public class MyClass {
    public void doSomething() {
        // ...
    }
}

Now in my code I want to do the following:

public class MainActivity extends AppCompatActivity {
    public interface Strategy {
        void doSomething();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Strategy oneClass = (Strategy)(new MyClass());
        Strategy twoClass = (Strategy)(new LibraryClass());
        oneClass.doSomething();
        twoClass.doSomething();
    }
}

In this case the method exists, so the interface is technically valid, but it wasn't explicitly implemented. When I tried doing this, it threw a run-time error:

java.lang.ClassCastException: MyClass cannot be cast to MainActivity$Controls

Worst-case scenario I know I can use a Proxy pattern to wrap LibraryClass in something that does implement the Strategy interface:

public class LibraryClassProxy implements Strategy {
    private LibraryClass internal;
    public void LibraryClassProxy() {
        internal = new LibraryClass();
    }
    public void doSomething() {
        internal.doSomething();
    }
}

But I'd prefer to avoid this if possible - in particular because the class I'm extending implements a lot of other interfaces, and I'd rather not have to proxy every single public method.

Aucun commentaire:

Enregistrer un commentaire