简体   繁体   English

使用泛型:使用泛型中的父级和子级值实例化泛型类的对象

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

The question from the exam states: Write a class called Registration which can store variables of type T, where T can be replaced with String, Person, Student, etc.. It should be possible to instantiate Registration as follows: 考试中的问题指出:编写一个名为Registration的类,该类可以存储类型T的变量,其中T可以用String,Person,Student等替换。应该可以如下实例化Registration:

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

I am unable to figure out how to write the declaration for the generics part of the class header. 我无法弄清楚如何为类头的泛型部分编写声明。 Below I have given the Registration class. 下面我给了Registration类。 To note, the class Student inherits the Person class. 注意,类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();
}
}

**Taken from Uoft CSC207 Aug2017 Exam **摘自Uoft CSC207 2017年8月考试

If Registration has to be generic enough to accept any type, eg. 如果Registration必须足够通用以接受任何类型,例如 String , then you should declare it as: String ,那么您应该将其声明为:

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

The following snippet would do, note that 以下代码片段可以做到,请注意

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

is not possible so rewritten at the bottom. 无法执行,因此请在底部重写。

    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>();
    }

The question is wrong or you've copied it incorrectly somehow. 这个问题是错误的,或者您以某种方式错误地复制了它。 There exists no such class declaration that can satisfy this instantiation. 没有可以满足此实例化的此类声明。

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

This is because by placing the object in r you allow its constraints to be violated. 这是因为通过将对象放在r您可以违反其约束。

For instance: 例如:

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!

This happens because r0 and r1 are the same object and so have the same last instance - a Person instance. 发生这种情况是因为r0r1是相同的对象,因此具有相同的最后一个实例-Person实例。 But the generic type of r0 promises that it's return type is Student. 但是r0的通用类型保证它的返回类型是Student。 That is why you cannot assign generics in the same way you can with normal types. 这就是为什么您不能以与普通类型相同的方式分配泛型的原因。 This is why you wildcards have their place. 这就是为什么通配符有其位置的原因。 It means the generic type can only be used to return things of that type eg. 这意味着通用类型只能用于返回该类型的东西,例如。 <? extends Person> <? extends Person> , but not pass them as parameters. <? extends Person> ,但不将其作为参数传递。 Or it means that the generic type can only be passed things of that type <? super Student> 还是意味着通用类型只能传递该类型的东西<? super Student> <? super Student> , but not return them. <? super Student> ,但不将其返回。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM