2

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?是否可以不使用任何类型的泛型?

4

3 回答 3

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!
于 2013-03-13T17:18:33.573 回答
1

java中没有办法确保一个对象字段继承/实现两个不同的类。假设您可以控制这里的所有对象,最简单的解决方法是让您的基类实现 Fooable。

于 2013-03-13T17:24:44.040 回答
0

由于您使用分配方法来设置字段,因此您可以在该方法中使用 instanceof 检查它是否是正确的对象类型。

public void assign(BaseClass baseClass) {
    if (baseClass instanceof foo)
       field3 = baseClass;
}

如果提供了未实现 foo 的类,您可能会抛出异常。

编辑:Doh,没有看到修复应该是编译时的。

于 2013-03-13T17:23:14.103 回答