使用需要假设 A 的版本覆盖方法 m(List<A> listOfA) 是 class B 扩展 A 而不必强制转换每个元素

Overriding a method m(List<A> listOfA) with a version that needs to assume A's are of class B extending A without having to cast each element

只是 运行 进入了一个我以前从未见过的建模问题。

假设我有一个 class 给法国人,另一个给医生,另一个给 FrenchDoctors,我想写以下内容:

///////// FRANCE

interface FrenchPerson {}

void frenchSpecificBureaucraticProcedure(List<? extends FrenchPerson> frenchPeople) {
    // ...
}

///////// DOCTORS

interface Doctor {}

class DoctorsAssociation {
    void includeNewMembers(List<? extends Doctor> doctors) {
        // ... do stuff
    }       
}

///////// FRENCH DOCTORS

interface FrenchDoctor extends FrenchPerson, Doctor {}

class FrenchDoctorsAssociation extends DoctorsAssociation {

    @Override
    void includeNewMembers(List<? extends Doctor> frenchDoctors) {
        // ERROR: frenchDoctors is List<? extends Doctors>
        // but frenchSpecificBureaucraticProcedure requires List<? extends FrenchDoctor>
        frenchSpecificBureaucraticProcedure(frenchDoctors);

        super.includeNewMembers(frenchDoctors);
    }
}

我的第一个冲动是使用 List<? extends FrenchDoctor> 参数替代 includeNewMembers

    @Override
    void includeNewMembers(List<? extends FrenchDoctor> frenchDoctors) {
        frenchSpecificBureaucraticProcedure(frenchDoctors);
        super.includeNewMembers(frenchDoctors);
    }

但这不起作用,因为 Java 编译器认为这是一种不同于 DoctorsAssociation::includeNewMembers 的方法。

我让它工作的唯一方法是进行未经检查的转换:

    @Override
    void includeNewMembers(List<? extends Doctor> frenchDoctors) {
        @SuppressWarnings("unchecked")
        List<FrenchDoctor> frenchFrenchDoctors = (List<FrenchDoctor>) frenchDoctors;
        frenchSpecificBureaucraticProcedure(frenchFrenchDoctors);
        super.includeNewMembers(frenchDoctors);
    }

但我想知道是否有更优雅的方法来做到这一点(即没有未经检查的转换)。

您可以使 DoctorsAssociation class 通用:

public class DoctorsAssociation<T extends Doctor> {
   void includeNewMembers(List<T> doctors) {
        // ... do stuff
    }
}   

然后将您的 FrenchDoctorsAssociation class 声明为

public class FrenchDoctorsAssociation extends DoctorsAssociation<FrenchDoctor> {

    @Override
    void includeNewMembers(List<FrenchDoctor> frenchDoctors) {
       // you now already have List<FrenchDoctor> to work with without casting
    }
}