2015-04-30 120 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對象。作爲一個更好的選擇,你必須實現一種新的方法,以確定現有的學生證的