Java 如何更改继承类中的集合类型?

Java 如何更改继承类中的集合类型?,java,inheritance,Java,Inheritance,我有一个基类,它定义了一个集合列表。现在,一个扩展基类的特定类应该更改集合类型 可能吗 public class Request { private List<Person> persons; //getter, setter } public class SubRequest1 extends Request { } public class SubRequest2 extends Request { } //only this class should

我有一个基类,它定义了一个集合
列表
。现在,一个扩展基类的特定类应该更改集合类型

可能吗

public class Request {
    private List<Person> persons;

    //getter, setter
}


public class SubRequest1 extends Request {
}

public class SubRequest2 extends Request {
}

//only this class should define a different list type
public class SubRequest3 {
    private List<SubRequest3.Person> persons;

    //compiler error. this is invalid code!
    @Override
    public List<SubRequest3.Person> getPersons() {
        return persons;
    }

    @Override
    public void setPersons(List<SubRequest3.person> persons) {
        this.persons = persons;
    }

    static class SubRequest3.Person extends Person {

    }
}
公共类请求{
私人名单人员;
//盖特,塞特
}
公共类SubRequest1扩展了请求{
}
公共类SubRequest2扩展了请求{
}
//只有此类应定义不同的列表类型
公共类子请求3{
私人名单人员;
//编译器错误。这是无效代码!
@凌驾
公众人士名单{
返回人员;
}
@凌驾
公众人士(名单人士){
这个人=人;
}
静态类SubRequest3.Person扩展Person{
}
}

不,不可能。不能覆盖字段,只能将其隐藏

处理这种情况的正确方法是将
Person
声明为公共接口。
Request
的子类可以使用
Person
的不同实现,但是调用代码可能不关心具体类型

interface Person
{
    //...
}

interface Request<T extends Person>
{
    void setPeople(List<T> person);
    List<T> getPeople();
}

abstract class DefaultRequest implements Request<Person>
{
    private List<Person> persons;

    public void setPeople(List<Person> people) { /* ... */ }
    public List<Person> getPeople()  { /* ... */ }
}

class SubRequest1 extends DefaultRequest 
{
    //...
}

class SubRequest2 extends DefaultRequest 
{
    //...
}

class SubRequest3 implements Request<SpecialPerson>
{
    private List<SpecialPerson> persons;

    public void setPeople(List<SpecialPerson> people) { /* ... */ }
    public List<SpecialPerson> getPeople()  { /* ... */ }
}
接口人
{
//...
}
接口请求
{
无效人员(名单人员);
列出getPeople();
}
抽象类DefaultRequest实现请求
{
私人名单人员;
public void setPeople(列出人员){/*…*/}
公共列表getPeople(){/*…*/}
}
类SubRequest1扩展了DefaultRequest
{
//...
}
类SubRequest2扩展了DefaultRequest
{
//...
}
类SubRequest3实现请求
{
私人名单人员;
public void setPeople(列出人员){/*…*/}
公共列表getPeople(){/*…*/}
}

不,不可能。不能覆盖字段,只能将其隐藏

处理这种情况的正确方法是将
Person
声明为公共接口。
Request
的子类可以使用
Person
的不同实现,但是调用代码可能不关心具体类型

interface Person
{
    //...
}

interface Request<T extends Person>
{
    void setPeople(List<T> person);
    List<T> getPeople();
}

abstract class DefaultRequest implements Request<Person>
{
    private List<Person> persons;

    public void setPeople(List<Person> people) { /* ... */ }
    public List<Person> getPeople()  { /* ... */ }
}

class SubRequest1 extends DefaultRequest 
{
    //...
}

class SubRequest2 extends DefaultRequest 
{
    //...
}

class SubRequest3 implements Request<SpecialPerson>
{
    private List<SpecialPerson> persons;

    public void setPeople(List<SpecialPerson> people) { /* ... */ }
    public List<SpecialPerson> getPeople()  { /* ... */ }
}
接口人
{
//...
}
接口请求
{
无效人员(名单人员);
列出getPeople();
}
抽象类DefaultRequest实现请求
{
私人名单人员;
public void setPeople(列出人员){/*…*/}
公共列表getPeople(){/*…*/}
}
类SubRequest1扩展了DefaultRequest
{
//...
}
类SubRequest2扩展了DefaultRequest
{
//...
}
类SubRequest3实现请求
{
私人名单人员;
public void setPeople(列出人员){/*…*/}
公共列表getPeople(){/*…*/}
}

子类无法重写方法并更改返回类型。有两种可能的方式允许子类在person列表中发送不同类型的元素

两者都假设
SpecialPerson
Person
的子类:

public class Request<T extends Person> {
    private final List<T> people = new ArrayList<>(); // or any other implementation

    public void setPeople(List<? extends T> people){
        this.people.clear();
        this.people.addAll(people);
    }

    public List<T> getPeople(){
        return people;
    }
}
1-使
请求
类成为通用类:

public class Request<P extends Person> {
    private List<P> persons;

    public List<P> getPersons() {
       //...
    }
}
所有其他
子请求
类将声明
扩展请求

2-将所有内容保持在API级别,如is,但将
SubRequest3.Person
的实例添加到列表中,而不是尝试返回一些
list
。这利用了
Person/SubRequest3.Person
继承,同时避免了与
列表相关的不变性问题

个人名单;
公众人士(名单人士){
//逐元素铸造
this.persons.clear();//或任何重置方法
people.stream().forEach(p->persons.add((SubRequest3.Person)p));
}
公共列表getPersons(){
//还可以使用循环并手动添加到“列表”对象
返回this.persons.stream().map(p->(Person)p.collect(Collectors.toList());
}

子类无法重写方法并更改返回类型。有两种可能的方式允许子类在person列表中发送不同类型的元素

两者都假设
SpecialPerson
Person
的子类:

public class Request<T extends Person> {
    private final List<T> people = new ArrayList<>(); // or any other implementation

    public void setPeople(List<? extends T> people){
        this.people.clear();
        this.people.addAll(people);
    }

    public List<T> getPeople(){
        return people;
    }
}
1-使
请求
类成为通用类:

public class Request<P extends Person> {
    private List<P> persons;

    public List<P> getPersons() {
       //...
    }
}
所有其他
子请求
类将声明
扩展请求

2-将所有内容保持在API级别,如is,但将
SubRequest3.Person
的实例添加到列表中,而不是尝试返回一些
list
。这利用了
Person/SubRequest3.Person
继承,同时避免了与
列表相关的不变性问题

个人名单;
公众人士(名单人士){
//逐元素铸造
this.persons.clear();//或任何重置方法
people.stream().forEach(p->persons.add((SubRequest3.Person)p));
}
公共列表getPersons(){
//还可以使用循环并手动添加到“列表”对象
返回this.persons.stream().map(p->(Person)p.collect(Collectors.toList());
}

您可以声明您的类以接受泛型类型
T
,该泛型类型
扩展Person

public class Request<T extends Person> {
    private final List<T> people = new ArrayList<>(); // or any other implementation

    public void setPeople(List<? extends T> people){
        this.people.clear();
        this.people.addAll(people);
    }

    public List<T> getPeople(){
        return people;
    }
}
公共类请求{
private final List people=new ArrayList();//或任何其他实现

public void setPeople(List您可以声明您的类以接受泛型类型
T
,它
扩展Person

public class Request<T extends Person> {
    private final List<T> people = new ArrayList<>(); // or any other implementation

    public void setPeople(List<? extends T> people){
        this.people.clear();
        this.people.addAll(people);
    }

    public List<T> getPeople(){
        return people;
    }
}
公共类请求{
private final List people=new ArrayList();//或任何其他实现

public void setPeople(列表创建一个由Person和SubRequest3.Person实现的接口。然后让您的getperson()和setperson使用该接口。创建一个由Person和SubRequest3.Person实现的接口。然后让您的getperson()使用该接口SetPerson使用该接口。所以我必须创建一个由每个子请求实现的通用接口?我是否也可以直接在
请求中实现该接口,所以我不必这样做