2015-04-30 119 views
0

我想了解如何inhertitance和ArrayList的工作,所以我有这个下面的代码 它有一类就是数据将被保存继承型铸造编译错误

public class Database { 
    ArrayList<Student> students; 
    ArrayList<Course> courses; 

    public boolean doesIDExist(ArrayList<RegistrationSystem> array, int id){ 
     boolean exist = false; 
     for (RegistrationSystem array1 : array) { 
      if (array1.getId() == id) { 
       exist = true; 
       break; 
      } 
     } 
     return exist; 
    } 

    public boolean addStudent(int id, String name, String surname){ 
     if(doesIDExist(students, id)){ 
      return false; 
     } 

     students.add(new Student(id, name, surname)); 
     return true; 
    } 

} 

学生和课程数据库是登记制度

public class RegistrationSystem { 
    protected int id; 

    public int getId() { 
     return id; 
    } 
} 

的子类,但我得到这一行的错误:

 if(doesIDExist(students, id)) 

incompatible types: ArrayList<Student> cannot be converted to ArrayList<RegistrationSystem>

我不明白为什么我会得到这个错误!

+2

你可能想使该'RegistrationSystem'超类,而不是一个接口......学生说“是”或RegistrationSystem课程“是一个” RegistrationSystem是没有意义的,所以有它们之间的继承关系可能也没有意义。 –

回答

1

虽然StudentRegistrationSystem一个亚型,它是ArrayList<Student>ArrayList<RegistrationSystem>一个亚型的情况。

原因是这可能导致非类型安全的代码。请看下面的代码:

void method1(ArrayList<RegistrationSystem> listOfRegistrationSystems) { 
    listOfRegistrationSystems.add(new Course()); 
} 
void method2() { 
    ArrayList<Student> listOfStudents = new ArrayList<>(); 
    method1(listOfStudents); 
    Student student = listOfStudents.get(0); 
    // Ooops! The first element of listOfStudents is not a Student! 
} 

为了解决这个问题,Java提供类型变量和界通配符。您可以使用ArrayList<? extends RegistrationSystem>,这意味着:某个未知子类RegistrationSystem的实例的一个ArrayList。在你的情况下,ArrayList<? extends RegistrationSystem>可以是ArrayList<RegistrationSystem>,ArrayList<Student>ArrayList<Course>之一。所以,你必须改变你的方法

public boolean doesIDExist(ArrayList<? extends RegistrationSystem> array, int id){ 
    boolean exist = false; 
    for (RegistrationSystem array1 : array) { 
     if (array1.getId() == id) { 
      exist = true; 
      break; 
     } 
    } 
    return exist; 
} 
+0

优秀的解释。为了增加这一点,值得注意的是:a)泛型类型本身_can_可以在其子类型的调用语句中被替换(例如,采用'List <?extends Number>'的方法可以接受'ArrayList ')和b )在使用通配符语法时,您只能获得上限类型的实例(例如'RegistrationSystem'不在集合中,最重要的是,您不能将任何东西放入集合中 - 请参阅[PECS](http:// stackoverflow.com/questions/2723397/java-generics-what-is-pecs) –

5

您的方法预计列表RegistrationSystem而不是列表Student

你必须更改为:

public boolean doesIDExist(ArrayList<? extends RegistrationSystem> array, int id){ 
+0

也许有必要更详细地解释一下上界的通配符,而不仅仅是在这里提供解决方案。请参阅[Oracle教程 - 上界限通配符](https://docs.oracle.com/javase/tutorial/java/generics/upperBounded。html) – SubOptimal

+1

扩展@Jens回答,ArrayList 或ArrayList 都不是'ArrayList '的子类型;你必须使用通配符语法'?在这种情况下扩展RegistrationSystem',使您的方法足够灵活,可以接受任何'RegistrationSystem'子类型的集合。 –

0

什么你想在这里做的是这样的:

ArrayList<RegistrationSystem> array = students;

Java不允许这种

更改方法签名这样做而不是doesIDExist(ArrayList<? extends RegistrationSystem>,int id)

0

当方法仅接受RegistrationSystem时,您正试图传递一个Student对象的ArrayList。

1

在这里if(doesIDExist(students, id),您正在通过Student对象而不是RegistrationSystem对象。作为一个更好的选择,你必须实现一种新的方法,以确定现有的学生证的