簡體   English   中英

在擴展類上,我可以使用實現多個接口的類的getter和setter方法嗎

[英]On a extended class, can i use a getter and setter of a class that implements multiple interfaces

我有一個帶有通用代碼的Java包,它將在團隊中分發以在兩個項目上工作。

一個項目已經在進行中,因此我必須調整現有代碼以使用此新程序包。

該軟件包具有類似於以下內容的接口和類:

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(){

}

想法是通過以下方式使用代碼:

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方法上工作?

這一切都取決於接口的實際合同 您將其指定為

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

但是...是否可以保證方法getPeople返回與先前setPeople調用中傳遞的列表(引用)相同的列表(引用)? 並保證它是可變的嗎?

如果您對兩個問題的回答均為“真”,那么您將無法做您想做的事情。 在這種情況下,合同意味着您可以使用任意GroupPerson實現來執行group.getPeople().add(person) 將其設置為僅接受Doctor實例的List<Doctor>會違反該合同。

如果列表不需要可變,則可以執行以下操作:

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

在Java 8之前,您必須使用

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

之所以可行,是因為List<Doctor>保證在檢查時返回Person實例,但是您不能添加任意Person實例,因為這樣的修改嘗試在運行時會被拒絕。

但這意味着要添加Doctor實例,您必須在某處保留對原始List<Doctor>的引用。

如果應該讓Group持有Person但不保留對setPeople調用者提供的List實例的引用,那將完全不同。 然后,通用簽名可以像這樣放寬:

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成為具有指定其成員類型的類型參數的泛型類,但是如果您必須處理已經存在的代碼,那可能是不可能的更改。

如果將醫生添加到由getPeople()表示的列表中,則它將透明地工作,因為它實現了Person

順便說一句:您的方法應稱為analizePeople以符合Java方法命名約定。

這不會工作:

public void AnalizePeople(Group group){
    List<Person> items=group.getPeople();

因為Group沒有定義getPeople

這會令人困惑:

public class Group extends AbstractGroup(){

因為已經有一個名為Group的接口。

“有沒有辦法讓分組班級保存一個Doctor列表,並且仍然使用Analizer類中的AnalizePeople方法?”

AnalizePeople(sic)在Analizer類中。 您的新班級Group當前與Analizer沒有關系,因此將無法調用AnalizePeople()。

請通過縮進至少4個空格來正確格式化代碼。 同樣,方法名稱應以小寫字母開頭。 並且“分析”應拼寫為“ y”而不是“ i”。

目前還不清楚您到底想實現什么目標,而目前正在問什么卻完全是胡言亂語。 請澄清。

暫無
暫無

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

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