Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 扩展接口时返回子元素列表_Java_Generics_Overloading_Generic List - Fatal编程技术网

Java 扩展接口时返回子元素列表

Java 扩展接口时返回子元素列表,java,generics,overloading,generic-list,Java,Generics,Overloading,Generic List,我正在开发一个库,在将返回类型重写为子元素列表时遇到了一个问题 一开始是这样的, Class Student { } public interface A { public Student isCurrentStudent(String name); public List<Student> getStudentList(); } public interface B extends A {

我正在开发一个库,在将返回类型重写为子元素列表时遇到了一个问题

一开始是这样的,

    Class Student {
    }

    public interface A {
        public Student isCurrentStudent(String name);
        public List<Student> getStudentList();
    }

    public interface B extends A {
        public List<Student> getColleges();
        public Student getBestFriend();
    }
B bObject = getBObject();
List<Student> studentList = bObject.getColleges();

D dObject = getDObject();
List<SeniourStudent> seniorStudentList = dObject.getColleges();
班级学生{
}
公共接口A{
公共学生是当前学生(字符串名称);
公共列表getStudentList();
}
公共接口B扩展了{
公开大学名单();
公立学生获得最佳朋友();
}
然后我想介绍SeniourStudent类和access SeniourStudent的API,所以我提出了以下建议:

Class SeniorStudent extends Student{
}

public interface C extends A {
    public SeniorStudent isCurrentStudent(String name);
    public List<SeniorStudent> getStudentList();
    public void addStudent(Attributes s);
}

public interface D extends B,C {
    public List<SeniorStudent> getColleges();
    public Student getBestFriend();
}
班高年级学生扩展学生{
}
公共接口C扩展了{
公共高级学生是当前学生(字符串名称);
公共列表getStudentList();
公立学校学生;
}
公共接口D扩展了B,C{
公开大学名单();
公立学生获得最佳朋友();
}
问题从接口C和D开始。因为java支持协变返回类型,所以C的第一个方法不会给出错误。但是当返回类型为“List”时,这就产生了麻烦。因此,我已将上述接口更改为使用泛型

public interface A <T extends Student> {
    public Student isCurrentStudent(String name);
    public List<T> getStudentList();
}

public interface B<T extends Student> extends A<T> {
    public List<T> getColleges();
    public Student getBestFriend();
}

public interface C extends A<SeniorStudent> {
    public SeniorStudent isCurrentStudent(String name);
    public List<SeniorStudent> getStudentList();
    public void addStudent(Attributes s);
}

public interface D extends B<SeniorStudent>,C {
    public List<SeniorStudent> getColleges();
    public SeniorStudent getBestFriend();
}
公共接口A{
公共学生是当前学生(字符串名称);
公共列表getStudentList();
}
公共接口B扩展了{
公开大学名单();
公立学生获得最佳朋友();
}
公共接口C扩展了{
公共高级学生是当前学生(字符串名称);
公共列表getStudentList();
公立学校学生;
}
公共接口D扩展了B,C{
公开大学名单();
公共高年级学生getBestFriend();
}
我相信这个设计是可以改进的,这样B类的实现者可以被限制为只使用Student类

我最终想要的是,提供干净的API,可以像这样使用

    Class Student {
    }

    public interface A {
        public Student isCurrentStudent(String name);
        public List<Student> getStudentList();
    }

    public interface B extends A {
        public List<Student> getColleges();
        public Student getBestFriend();
    }
B bObject = getBObject();
List<Student> studentList = bObject.getColleges();

D dObject = getDObject();
List<SeniourStudent> seniorStudentList = dObject.getColleges();
B bObject=getBObject();
List studentList=bObject.getColleges();
D dObject=getDObject();
List seniorStudentList=dObject.getColleges();
如果在返回类型是子元素列表时有一种方法覆盖它,那么整个问题就可以解决了

因为我的实际代码要大得多,所以我在这里使用了一个简单的示例来描述这个问题。希望它足够清晰


编辑

为B引入一个BS超类型将解决这个问题。但这是更干净的方式吗

public interface A <T extends Student> {
    public Student isCurrentStudent(String name);
    public List<T> getStudentList();
}

public interface BS<T extends Student> extends A<T> {
    public List<T> getColleges();
    public Student getBestFriend();
}

public interface B extends BS<Student> {
    public List<Student> getColleges();
    public Student getBestFriend();
}

public interface C extends A<SeniorStudent> {
    public SeniorStudent isCurrentStudent(String name);
    public List<SeniorStudent> getStudentList();
    public void addStudent(Attributes s);
}

public interface D extends BS<SeniorStudent>,C {
    public List<SeniorStudent> getColleges();
    public SeniorStudent getBestFriend();
}

公共接口A{
公共学生是当前学生(字符串名称);
公共列表getStudentList();
}
公共接口BS扩展了{
公开大学名单();
公立学生获得最佳朋友();
}
公共接口B扩展了BS{
公开大学名单();
公立学生获得最佳朋友();
}
公共接口C扩展了{
公共高级学生是当前学生(字符串名称);
公共列表getStudentList();
公立学校学生;
}
公共接口D扩展了BS,C{
公开大学名单();
公共高年级学生getBestFriend();
}

谢谢,

我有点不明白你到底想做什么。但我想,您的问题可以通过不使接口
C
D
通用化来解决。您可以使用如下界面:

interface A<T extends Student> {
    public T isCurrentStudent(String name);
    public List<T> getStudentList();
}

interface B<T extends Student> extends A<T> {
    public List<T> getColleges();
}

interface C extends B<Student> {
    public Student isCurrentStudent(String name);
    public List<Student> getStudentList();
    public List<Student> getColleges();
}

interface D extends B<SeniorStudent> {
    public SeniorStudent isCurrentStudent(String name);
    public List<SeniorStudent> getStudentList();
    public List<SeniorStudent> getColleges();
}
接口A{
公共T是当前学生(字符串名称);
公共列表getStudentList();
}
接口B扩展了A{
公开大学名单();
}
接口C扩展了B{
公共学生是当前学生(字符串名称);
公共列表getStudentList();
公开大学名单();
}
接口D扩展了B{
公共高级学生是当前学生(字符串名称);
公共列表getStudentList();
公开大学名单();
}

然后,让你的班级分别为
Student
seniordstudent
实现接口
C
D
。这是我能想到头顶的唯一方法。看看你是否能接受这个,否则我们可以试着在这方面做进一步的即兴创作。

正如Plínio Pantaleão在评论中所说(或者实际上,我想说),你可以定义接口来返回
列表你的基本接口(a和B)可以返回列表你可能是指
列表对于接口D,我也想从B继承方法。对不起,我可能不清楚这个问题。我指的是这个问题。根据问题,它是D和B。根据你的答案,它是D和C。正如你所看到的,我正在覆盖getColleges()方法,而B(wrt qustion或C wrt answer)包含更多不需要覆盖的方法。@DarRay那么你想让我答案中的接口
C
没有
getColleges()
方法吗?我还不清楚你到底想要什么。我无法连接我的答案中的
C
与问题中的
B
的相似之处。我之前对你的答案有点困惑,但如果我理解正确,如果我为B(wrt问题)引入一个child类(比如childB),它将与你的答案相匹配。所以我应该实现childB和D,而不是实现B和D。我确实这样想,但是我们不能有很多清晰的设计吗?事实上我已经在做同样的事情了,不是吗?我使用,public List getColleges();在创建对象时强制定义类型T。我这样做是因为我有更多的方法必须返回Student或SeniourStudent列表(取决于B或D),并且希望所有这些方法只返回一个类型,该类型定义了创建对象的时间。我用需要实现的预期行为更新了问题。你有什么建议吗?@DarRay我用编辑更新了答案,但可能有点棘手,因为一个方法是用不同的返回类型继承的……是的,还有其他方法是从B继承到D的。我对问题进行了编辑,添加了“public SeniorStudent getBestFriend();”来表示这些方法。我目前的设计与你们的答案有些相似,也和@RohitJain所说的一致。基本上,我所做的是引入一个新的interf
import java.util.List;

public class StudentsReturnTypesTest
{
    public static void main(String[] args)
    {
        B bObject = getBObject();
        List<Student> studentList = bObject.getColleges();
        bObject.methodThatWasInB();

        D dObject = getDObject();
        List<SeniorStudent> seniorStudentList = dObject.getColleges();
        dObject.methodThatWasInB();
    }

    private static D getDObject() { return null; }
    private static B getBObject() { return null; }
}

interface A<T extends Student> {
    public Student isCurrentStudent(String name);
    public List<T> getStudentList();
}

interface AS extends A<Student> { }

interface B extends AS, AdditionalMethodsThatHaveBeenInB {
    public List<Student> getColleges();
}

interface AdditionalMethodsThatHaveBeenInB {
    void methodThatWasInB();
}

interface C extends A<SeniorStudent> {
    public SeniorStudent isCurrentStudent(String name);
    public List<SeniorStudent> getStudentList();
    public void addStudent(Attributes s);
}

interface D extends C, AdditionalMethodsThatHaveBeenInB {
    public List<SeniorStudent> getColleges();
}

interface Attributes {}
interface Student {}
interface SeniorStudent extends Student {}