【问题标题】:Interfaces, inheritance and subtyping接口、继承和子类型
【发布时间】:2010-11-22 11:06:02
【问题描述】:

我有以下 JAVA 乱七八糟的东西,我不太清楚:

具有两个泛型 A 和 B 的泛型接口,例如 AIter<A,B>

另一个泛型接口和一个额外的泛型类型 C,像这样:BIter<A,B,C> extends AIter<A,B>

一个泛型类ClassA<D>,它递归地将第一个接口AIter实现为一个内部类,如下所示:ThisIter implements AIter<Something,ThisIter>

另一个泛型类ClassB<D,E>,它递归地将第二个接口 BIter 实现为内部类,如下所示:ThisIter implements BIter<Something,ThisIter,SomethingElse>

这两个类都有一个名为 public ThisIter giveIter(); 的函数,它应该返回内部类的一个实例(每个内部类都有一个类似的函数,它也返回一个自身的新实例,但参数不同)。

是否可以将 ClassB 实现为 ClassA 的子类型? (假设泛型Types相同,如ClassA<MyString>ClassB<MyString, somethingelse>

我似乎无法实现,因为 ThisIter 的实例以及 giveIter() 的返回类型不兼容。

一般来说,子接口(n)的实现是接口本身实现的子类型吗?

IterA

public interface IterA<A,B> {}

IterB

public interface IterB<A,B,C> extends IterA<A,B> {}

A 类:

public class ClassA<L> {
    Node root;

    public ClassA() {
        root= new Node();
    }

    protected class Node {
       /*...*/
    }

    protected class Edge {
        /*...*/
        L varL;
    }

    protected class ThisIter implements IterA<Edge,ThisIter> {
    /*...*/
    }
    public IterA<Edge,ThisIter> assoc() {
        return new ThisIter(root);
    }
}

B 类:

public class ClassB<L,N> {
    Node root;

    public ClassB() {
        root= new Node();
    }

    protected class Node {
       /*...*/
       N varN;
    }

    protected class Edge {
        /*...*/
       L varL;
    }

    protected class ThisIter implements IterB<Edge,ThisIter,N> {
    /*...*/
    }
    public IterB<Edge,ThisIter,N> assoc() {
        return new ThisIter(root);
    }
}

【问题讨论】:

    标签: java generics inheritance interface subtype


    【解决方案1】:

    我们不能覆盖内部类。阅读here 关于内部类可以被覆盖

    问。是否可以将 ClassB 实现为 ClassA 的子类型?

    A.是的,您需要为您的ClassB.getIter() 选择一个不同的名称。否则,它会抱怨被覆盖的方法有不同的返回类型或其他东西。实际上,您并不打算覆盖它,但编译器无法知道。因此,您需要为其选择其他名称。

    问。一般来说,子接口的实现(n)是否是接口本身实现的子类型?

    A.不,在这种情况下,它将是 2 个不同的类层次结构。一个从上到下,interfaceA -> interfaceB -> classD,另一个 interfaceA -> classC。

    【讨论】:

    • 如果a有一个接口A,另一个接口B,扩展了接口A,是接口B的实现(D类),是接口A的实现(C类)的子类型?跨度>
    • @Bernd:不,在这种情况下,它将是 2 个不同的类层次结构。一个从上到下,interfaceA -> interfaceB -> classD,另一个 interfaceA -> classC。
    【解决方案2】:

    重新考虑您的命名和代码分解,尤其是您的每个容器类中是否真的需要一个名为 node 和 edge 的类?

    这是可编译的,类似于您的代码(据我了解其意图。)

        interface IterA<A,B> {}
        interface IterB<A,B,C> extends IterA<A,B> {}
    
        class ClassA<L> {
            NodeA root;
            public ClassA() { root= new NodeA(); }
            protected class NodeA { }
            protected class EdgeA { L varL; }
            protected class ThisIterA implements IterA<EdgeA, ThisIterA> { ThisIterA(NodeA root) { } }
    
            public IterA<? extends EdgeA, ? extends IterA> assoc() { return new ThisIterA(root); }
        }
    
        class ClassB<L,N> extends ClassA<L> {
            NodeB root;
            public ClassB() { root= new NodeB(); }
            protected class NodeB extends NodeA { N varN; }
            protected class EdgeB extends EdgeA { L varL; }
            protected class ThisIterB<EA extends EdgeA, TIA extends IterB> implements IterB<EA, TIA, N> { ThisIterB(NodeB root) { } }
    
            public IterB<EdgeB, IterB, N> assoc() { return new ThisIterB<EdgeB, IterB>(root); }
        }
    

    这里已经很晚了,所以这是我的最后一个。祝你好运,晚安!

    【讨论】:

    • 但这也不起作用,因为在 ClassA 和 ClassB 的类文件中,A、B、C 是不可解析的。我可以在 ClassB 和 AIter&lt;Something,ThisIter&gt; giveIter() {} in ClassA 中执行 `BIter giveIter() {},但随后它们又不兼容了..
    • 请粘贴一些骨架代码(最好是可编译的)。它可以工作,但很难理解你需要什么。
    • 你不粘贴的代码不会编译,因为没有绑定ABC参数。请发布一些可以编译并且有 2 个并行类的东西,你想使用泛型将它们放在同一个层次结构中。最好编辑您的原始问题,而不是将其塞进 cmets。
    • 在原问题中发布了一些
    • 您仍然缺少 IterA 和 IterB 的定义 - 根据您的解释,我知道一个有 2 个其他 3 个参数,而在查看用法时,两者似乎都有 2 个参数。
    【解决方案3】:

    不确定这是否有帮助,但以下编译

    interface AIter<A,B>{}
    interface BIter<A,B,C,D extends A,E extends B > extends AIter<A,B>{}
    
    class AClass{
        protected class Node {}
        protected class Edge {}
    
        public class ThisIter implements AIter<Node,Edge>{};
    
        public ThisIter getIter(){
            return new ThisIter();
        }
    }
    
    class BClass<N> extends AClass{
        protected class Node extends AClass.Node{}
        protected class Edge extends AClass.Edge{}
    
        public class ThisIter extends AClass.ThisIter implements BIter<AClass.Node,AClass.Edge, N, Node, Edge>{};
    
        @Override
        public ThisIter getIter(){
            return new ThisIter();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-01
      • 1970-01-01
      • 2013-02-19
      • 2013-02-25
      • 2020-03-02
      • 1970-01-01
      相关资源
      最近更新 更多