gpt4 book ai didi

java - 在扩展类上,我可以使用实现多个接口(interface)的类的 getter 和 setter

转载 作者:行者123 更新时间:2023-11-30 08:07:47 25 4
gpt4 key购买 nike

我有一个包含通用代码的 Java 包,它将分发给团队以处理两个项目。

一个项目已经在进行中,所以我必须调整现有代码以使用这个新包。

该包具有类似于以下的接口(interface)和类:

public interface Person{
}

public interface Group{
List<Person> getPeople();
void setPeople(List<Person> people);
}

public abstract AbstractPerson implements Person{
}

public abstract AbstractGroup implements Group{
List<Person> people;


public List<Person> getPeople(){
return this.items;
};

public void setPeople(List<Person> people){
this.people=people;
}
}

public class Analyzer(){

public void analyzePeople(Group group){

List<Person> items=group.getPeople();

....
}
}

一个已经在进行中的项目,我们有一个将像这样更改的类:

public class Doctor extends ExistingClass implements ExistingInterface,Person {

}

我没有组类,所以我要实现它,

public class CurrentGroup extends AbstractGroup(){

}

ideia 是按以下方式使用代码:

CurrentGroup currentGroup=new CurrentGroup();
currentGroup.setPeople(new ArrayList<Doctor>());
...

Analyzer analyzer=new Analyzer();
analyzer.analyzePeople(currentGroup);

我有两个问题:

  • 此类实现必须持有 Doctor 的集合;
  • 我当前代码中的集合是 ArrayLists;

由于 ArrayList 实现了 List 而 Doctor 实现了 Person,因此所有这一切都应该有效,但由于 Eclipse 显示错误“Processo 类型中的方法 setPeople(List<Person>) 不适用于参数 (ArrayList<Doctor>)”,所以它没有。

有什么方法可以让 CurrentGroup 类将 Doctor 列表保存为 ArrayList 并仍然处理类 Analizer 中的 AnalizePeople 方法?

最佳答案

这一切都取决于接口(interface)的实际契约。您将其指定为

public interface Group{
List<Person> getPeople();
void setPeople(List<Person> people);
}

但是……是否保证方法getPeople返回在先前 setPeople 中传递的相同列表(引用)调用?它是否保证可变

如果您对这两个问题的回答都是真,那么您将无法完成您想要做的事情。在这种情况下,契约(Contract)暗示您可以执行 group.getPeople().add(person)任意 GroupPerson实现。将其设置为 List<Doctor>只接受 Doctor实例会违反该契约(Contract)。

如果不需要列表是可变的,你可以这样做:

List<Doctor> list=…;
group.setPeople(Collections.unmodifiableList(list));

在 Java 8 之前,您必须使用

group.setPeople(Collections.<Person>unmodifiableList(list));

这行得通,因为 List<Doctor>保证返回Person被检查时的实例,但您不能添加任意 Person此类修改尝试在运行时会被拒绝。

但它暗示为了添加Doctor实例,您必须保留对原始 List<Doctor> 的引用某处。

如果 Group 就完全不同了s 应该持有 Person但不要保留对 List 的引用setPeople 的调用者提供的实例.然后,通用签名可以像这样放宽:

interface Group {
List<Person> getPeople();
void setPeople(List<? extends Person> people);
}
class AbstractGroup implements Group {
final ArrayList<Person> people=new ArrayList<>();

public List<Person> getPeople() {
return people; // or Collections.unmodifiableList(people)
}

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

然后,你可以简单地说

List<Doctor> list=…;
group.setPeople(list);

但是,要将组中的人员初始化为您的医生,您不能保证它仍然是一个同质的医生组(除非它是一个纯粹的本地对象,您不会将其交给可以修改它的代码) .

还有制作Group的选项具有指定其成员类型的类型参数的泛型类,但如果您必须处理已经存在的代码,那么这可能是不可能的更改。

关于java - 在扩展类上,我可以使用实现多个接口(interface)的类的 getter 和 setter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33518700/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com