Reputation: 1159
Java allows to assign subclass instances to class-typed fields, for example:
public class BaseClass {
}
public class SubClass extends BaseClass {
}
public class Example {
private BaseClass field1;
public void assign(SubClass subclass) {
field1 = subclass; // is OK
}
}
Java allows also to use interfaces as types. If we have an interface Fooable
,
public interface Fooable {
void foo();
}
our Example
class can have a field of type Fooable
,
Fooable field2;
That is, it is possible to assign to field2
an instance of any class implementing Fooable
interface.
But what if I want to tell the compiler that field3
has to be both an instance of BaseClass
and implementation of Fooable
interface? So that, if there is a class
public class FooSubClass extends BaseClass implements Fooable {
@Override
public void foo() {
// TODO
}
}
, I could assign to field3
instances of FooSubClass
but not of SubClass
?
Is it possible without using generics of any sort?
Upvotes: 2
Views: 90
Reputation: 24334
You can't do it like you are trying to.
You would need to define another class, perhaps an abstract class would suit you here:
public class abstract AbstractSubClass extends BaseClass implements Fooable {
...
}
Then FooSubClass
:
public class FooSubClass extends AbstractSubClass {
...
}
Then your field is:
private AbstractSubClass field1;
Which will accept FooSubClass
but not SubClass
Its the only way the compiler can guarantee that field1 will actually have implementations of all the required methods.
Here is a textbook example to illustrate:
public class Bird() {
public void eat() {
....
}
}
public interface FlyingBehaviour() {
void fly();
}
public abstract class FlyingBird extends Bird implements FlyingBehaviour() {
...
}
public class Eagle extends FlyingBird {
...
}
public class Penguin extends Bird {
...
}
FlyingBird bird = new Eagle();
bird.fly();
FlyingBird bird = new Penguin(); //Compilation Error - Penguins cant fly!
Upvotes: 8
Reputation: 5289
There is no way in java to ensure a object field inherits/implements two different classes. Assuming you have control of all the objects here, the easiest fix would be for your base class to implement Fooable.
Upvotes: 1
Reputation: 891
Since you are using a assign-method for setting the fields, you can check if it is correct type of object using instanceof in that method.
public void assign(BaseClass baseClass) {
if (baseClass instanceof foo)
field3 = baseClass;
}
You may throw an exception if class not implementing foo is provided.
edit: Doh, didn't see that the fix should be for compile-time.
Upvotes: 0