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使用该接口。所以我必须创建一个由每个子请求实现的通用接口?我是否也可以直接在请求中实现该接口,所以我不必这样做