Java允许将子类实例分配给类类型字段,例如:
public class BaseClass {
}
public class SubClass extends BaseClass {
}
public class Example {
private BaseClass field1;
public void assign(SubClass subclass) {
field1 = subclass; // is OK
}
}
Java还允许将接口用作类型。如果我们有一个接口Fooable
,
public interface Fooable {
void foo();
}
我们的Example
类可以包含Fooable
类型的字段,
Fooable field2;
也就是说,可以为field2
分配实现Fooable
接口的任何类的实例。
但是如果我想告诉编译器field3
必须 BaseClass
的实例和Fooable
接口的实现呢?所以,如果有一个类
public class FooSubClass extends BaseClass implements Fooable {
@Override
public void foo() {
// TODO
}
}
,我可以分配给field3
FooSubClass
但不是SubClass
的实例?
是否可以不使用任何类型的泛型?
答案 0 :(得分:8)
你不能像你想要的那样去做。
您需要定义另一个类,也许这里的抽象类适合您:
public class abstract AbstractSubClass extends BaseClass implements Fooable {
...
}
然后FooSubClass
:
public class FooSubClass extends AbstractSubClass {
...
}
然后你的领域是:
private AbstractSubClass field1;
哪个会接受FooSubClass
但不接受SubClass
它是编译器可以保证field1实际上具有所有必需方法的实现的唯一方法。
这是一个教科书示例来说明:
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!
答案 1 :(得分:1)
java中没有办法确保对象字段继承/实现两个不同的类。 假设您可以控制所有对象,最简单的方法是让您的基类实现Fooable。
答案 2 :(得分:0)
由于您使用assign方法设置字段,因此您可以使用该方法中的instanceof检查它是否是正确的对象类型。
public void assign(BaseClass baseClass) {
if (baseClass instanceof foo)
field3 = baseClass;
}
如果提供了未实现foo的类,则可能抛出异常。
编辑: Doh,没有看到修复应该是编译时。