【问题标题】:Is it possible to extend a class that has an instance of itself as a field such that the subclass has an instance of the subclass instead?是否可以扩展一个具有自身实例作为字段的类,以便子类具有子类的实例?
【发布时间】:2014-08-27 20:17:02
【问题描述】:

我知道您可以将 LinkedList 的实现分为两类。一方面,实际的 LinkedList 是对一些链接节点中的第一个的引用,就像这样

public class LinkedList1<E>{

    class Node{
        E data;
        Node next;
    }

    Node head;

}

那个版本可能更好,但或者,有一个更“直接”的版本,这使得删除头部(头部意味着从客户端的角度来看的第一个元素)之类的事情有点棘手,但仍然可以在 LinkedList2 的实例中进行:

public class LinkedList2<E>{

    E data;
    LinkedList2 next;

}

我很好奇是否有任何方法可以创建LinkedList2Child extends LinkedList2 使得next 字段的类型为LinkedList2Child,可能涉及反射?

编辑:这并不妨碍我完成任何事情,因为版本 1 可用 - 我只是对这个问题总体感到好奇,这是一个示例。

我知道您可以通过声明与父字段同名的字段来“隐藏”子类中的字段,但如果您想使用对该字段进行操作的父方法,这将不起作用。

【问题讨论】:

  • 为什么不想使用第一个版本?您所做的只是消除了链接列表,现在您只有节点,将列表本身的管理委托给客户端代码。这是没有意义的。我认为这是一个 XY 问题...请解释您要解决的实际问题,而 Collection 类无法解决。
  • 您不必将管理委托给客户端代码。您仍然可以在类中实现添加、删除等任何内容。并不是我不想使用第一个版本。它可能会更好。我只是想知道是否可以按照我描述的方式扩展后者。

标签: java inheritance reflection recursive-datastructures


【解决方案1】:

泛型:

public class LinkedList2<E, T extends LinkedList2>{

    E data;
    T next;

}

public class LinkedSubclass extends LinkedList2<LinkedSubclass> {

}

它受到对泛型所能做的通常限制(例如,在基类中构造新的“下一个”值需要接受子类型的类或工厂),但会涵盖你想要的。

【讨论】:

    【解决方案2】:

    这称为协方差(或协变返回类型):

    public static abstract class A
    {
        public A get() { ... }
    }
    
    public static abstract class B extends A
    {
        @Override
        public B get() { ... }
    }
    

    方法B#get() 覆盖A#get()。这与泛型正交(即概念上无关)。

    【讨论】:

    • 我认为它与泛型无关。我不确定我是否看到这如何允许在子类中有效地拥有子类的实例而不是父类的实例。如果我有一个二叉树并创建一个自平衡二叉树子类,该子类使用执行平衡操作的插入覆盖插入,该怎么办。当在自平衡树的子树中递归调用 insert 时,该子树也需要执行平衡操作,因此需要是自平衡子类的实例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-13
    相关资源
    最近更新 更多