5

I need to have a variable in a class which is an instance of class "ClassA" but which also implements interface "InterfaceI".

Obviously this can be done for one or the other easily:

private ClassA mVariable;
private InterfaceI mVaraible;

but how can I enforce the object both extends ClassA and implements InterfaceB? Something like:

private <? extends ClassA & InterfaceI> mVaraible;

is what I need but I have no idea of the syntax or if it is even possible. I will also need a get and set method, but that can be done with generics (I think?)

The obvious solution is

public class ClassB extends ClassA implements InterfaceI{
    //whatever here
}

However both InterfaceI and ClassA are part of an external libary, this libary has classes which extend ClassA and InterfaceI and I cant edit them to make them extend ClassB, therefore this solution will not work.

Mat
  • 202,337
  • 40
  • 393
  • 406
jtedit
  • 1,450
  • 2
  • 13
  • 27
  • 1
    You can't, basically. You could check it when setting the variable, and then cast when you need to... but you can't express that constraint on the variable itself, without making the class generic. – Jon Skeet Dec 14 '13 at 11:31
  • there's some magic in Java8 to allow multiple inheritance, or some sort of mix-in... – Thufir Dec 14 '13 at 11:32
  • @Jon Skeet How would you check it when setting the variable? – jtedit Dec 14 '13 at 11:32
  • are the classes final? if B extends A, why can't C extend B? I'm guessing B is final...or something. – Thufir Dec 14 '13 at 11:36
  • @jtedit: Well if you set it from a generic method, you can use the type system there. But otherwise, you can just use `if (x instanceof ...)` – Jon Skeet Dec 14 '13 at 11:37

2 Answers2

1

I have found a rather hacky workaround.

The class contains both a ClassA and InterfaceI reference as follows:

private ClassA mItemClassA;
private InterfaceI mItemInterfaceI;

The set method then looks like this:

public void setVaraible(ClassA item){
    assert (item instanceof InterfaceI);
    mItemClassA = item;
    mItemInterfaceI = (InterfaceI) item;
}

Other variations of this could be throwing an exception, returning false, etc if the item is not an instance of InterfaceI

Other methods in the class can then call functions from both InterfaceI and ClassA using mItemClassA and mItemInterfaceI.

I am not going to implement a get method for now, but if I did there would likely have to be a version to get the interface and a version to get the class.

jtedit
  • 1,450
  • 2
  • 13
  • 27
1

You can do this with the generic class types as this:

private class ClassB <R extends ClassA & InterfaceI> {
    R mVaraible;
}
Ali Nem
  • 5,252
  • 1
  • 42
  • 41