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
    }
}


,我可以分配给field3FooSubClass实例,但不能分配给SubClass的实例?
是否可以不使用任何泛型?

最佳答案

您无法像尝试那样去做。

您将需要定义另一个类,也许抽象类在这里适合您:

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!

10-06 09:42