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

use*_*967 2 java generics inheritance extends

刚遇到一个我以前没见过的建模问题.

假设我有一个法语人员课程,另一个为医生,另一个为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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的第一个冲动是includeNewMembers使用List<? extends FrenchDoctor>参数覆盖:

    @Override
    void includeNewMembers(List<? extends FrenchDoctor> frenchDoctors) {
        frenchSpecificBureaucraticProcedure(frenchDoctors);
        super.includeNewMembers(frenchDoctors);
    }
Run Code Online (Sandbox Code Playgroud)

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

我可以让它工作的唯一方法是做一个未经检查的演员:

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

但我想知道是否有更优雅的方法来做到这一点(也就是说,没有未经检查的演员表).

OH *_*ERS 7

你可以使这个DoctorsAssociation类通用:

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

然后宣布你的FrenchDoctorsAssociation班级为

public class FrenchDoctorsAssociation extends DoctorsAssociation<FrenchDoctor> {

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