簡體   English   中英

使用泛型:使用泛型中的父級和子級值實例化泛型類的對象

[英]Using Generics: Instantiating an object of a generic class with parent and child values in generic

考試中的問題指出:編寫一個名為Registration的類,該類可以存儲類型T的變量,其中T可以用String,Person,Student等替換。應該可以如下實例化Registration:

Registration<String> r1 = new Registration<String>();
Registration<Person> r2 = new Registration<Student>();

我無法弄清楚如何為類頭的泛型部分編寫聲明。 下面我給了Registration類。 注意,類Student繼承了Person類。

import java.util.List;
import java.util.ArrayList;
public class Registration<T extends Person> //I believe my issue is here{
private T [] roster;
private List<T> waitList;
private static int rosterCount;
private T lastInstance;

public Registration () {
    roster =  (T[]) new Object[100];
    waitList = new ArrayList<>();
    rosterCount = 0;
    lastInstance = null;
}

public void addIndex (T t) {
    if (rosterCount>=100) {
        waitList.add(t);
    }
    else {
        roster [rosterCount] = t;
        rosterCount++;
    }
    lastInstance = t;
}

public T getLastInstance() {
    return lastInstance;
}

public int getRosterCount() {
    return rosterCount;
}

public int getWaitListCount() {
    return waitList.size();
}
}

**摘自Uoft CSC207 2017年8月考試

如果Registration必須足夠通用以接受任何類型,例如 String ,那么您應該將其聲明為:

class Registration<T> {
    private T[] roster;
    ...
    public Registration (Class<T> clazz) {
        roster = (T[])Array.newInstance(clazz, 100);
    }
    ...
} 

以下代碼片段可以做到,請注意

Registration<Person> r2 = new Registration<Student>(); 

無法執行,因此請在底部重寫。

    static class Person  {}
    static class Student extends Person {}

    static class Registration<T> {
        private T[] roster;
        private List<T> waitList;
        static int rosterCount;
        private T lastInstance;

        public Registration() {
            roster =  (T[]) new Object[100]; ;
            waitList = new ArrayList<T>();
        }
    }

    public static void main(String[] args) {
        Registration<String> r1 = new Registration<String>();
        Registration<? extends Person> r2 = new Registration<Student>();
    }

這個問題是錯誤的,或者您以某種方式錯誤地復制了它。 沒有可以滿足此實例化的此類聲明。

Registration<Person> r = new Registration<Student>();

這是因為通過將對象放在r您可以違反其約束。

例如:

Registration<Student> r0 = new Registration<Student>();
r0.addIndex(new Student());
Student s0 = r0.getLastInstance(); // returns a student instance 
r0. addIndex(new Person());  // error, person is not a subclass of student 

Registration<Person> r1 = r0; // error, but we will pretend it's allowed - you could force it with a cast 
r1.addIndex(new Person()); // this is cool, but what happens to the underlying object? 
Person p = r1.getLastInstance(); // this is fine, just like before 
Student s1 = r0.getLastInstance(); // error, returns a person instance!

發生這種情況是因為r0r1是相同的對象,因此具有相同的最后一個實例-Person實例。 但是r0的通用類型保證它的返回類型是Student。 這就是為什么您不能以與普通類型相同的方式分配泛型的原因。 這就是為什么通配符有其位置的原因。 這意味着通用類型只能用於返回該類型的東西,例如。 <? extends Person> <? extends Person> ,但不將其作為參數傳遞。 還是意味着通用類型只能傳遞該類型的東西<? super Student> <? super Student> ,但不將其返回。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM