【问题标题】:How to extend a class with a member of its own type?如何使用自己类型的成员扩展类?
【发布时间】:2018-10-07 18:46:22
【问题描述】:

假设我们需要使用一个名为“BaseNode”的类来实现不同类型的树,从该类派生出其他类型的节点,并且假设有一个名为parent的实例变量,它自己的类型,通常看起来像:

class BaseNode{
   //...some fields
   BaseNode parent;
   //...other methods
}

现在,如果我要为具有更多成员的 AVL 树派生节点:

class AVLNode extends BaseNode{
    //...other useful stuff

}

原来的parent(&left&right)节点成员仍将是BaseNode类型,这会阻止我实现AVL树。 谁能告诉我我们如何解决这个继承问题? 谢谢!

【问题讨论】:

  • 你可以做BaseNode<T extends BaseNode>,但我可以看到这会导致更多的问题。很高兴知道为什么 parent 的类型必须与您选择实例化的子类型匹配 - 它以什么方式阻止您实现 AVL 树?
  • @VinceEmigh 不能说,我想我们可以找到一种方法来规避这个限制并让 BaseNode 变量引用 parent ,但我真正想知道的是如何解决一般来说,这个“用自己类型的成员扩展类”的问题,在这里我只是想举个例子。希望一旦尝试了您和 John Kugelman 提到的实现,我可以有一个大图景!
  • 您确定您尝试做的不是应该避免的设计缺陷吗?它似乎不会影响你实现 AVL 树的能力,所以你应该问自己:“我想要实现的这个设计有什么实际用途吗?”——从我的观点来看看来,我没有看到任何这样的设计目的,这可能是该语言没有投入资源来简化它的原因(设计师也没有看到目的)。你能详细说明你为什么要这样做吗?事实上,这样的设计似乎是设计师通常会尽量避免的。
  • 当我想得更多时,我什至找不到像这样的设计的单个用例。如果你能找到一个单一的目的,这样的设计可以简化你想要做的事情,我相信我可以用更坚固的设计将它击落。这种设计看起来很痛苦:AVLNode extends BaseNode<AVLNode> 用于BaseNode 的任何潜在子类型 - 似乎没有理由的过度冗长。我什至还没有分析潜在的问题,我已经建议不要这样做,除非你有需要这个的实际目的。
  • @VinceEmigh 也许这是真的,假设我们在BaseNode 中并不需要parent,但毕竟我们肯定需要leftright 任何Node 中的字段所以我们仍然期望有一个类,其中一个成员是它自己的类型,当然在某些时候我们需要扩展这个类,所以仍然会遇到“如何扩展这样的类”的问题,我只是在尝试举个例子,这不是真正的现实生活/家庭作业问题。

标签: java class oop inheritance extends


【解决方案1】:

解决方案 1 - 每当您访问 parent 时,将其转换为 (AVLNode) parent。您可以在AVLNode 中编写访问器以使其更方便。

class AVLNode extends BaseNode {
    public AVLNode getParent() {
        return (AVLNode) parent;
    }
}

解决方案 2 - 使 BaseNode 成为一个将子类作为参数的泛型类。现在parent 可以是所需的确切类型。

class BaseNode<T extends BaseNode<T>> {
    T parent;
}

class AVLNode extends BaseNode<AVLNode> {
}

【讨论】:

  • 您能给我举个例子,说明我们将如何声明BaseNodeAVLNode w/Solution2 的变量吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-05
  • 1970-01-01
  • 1970-01-01
  • 2019-08-11
  • 2012-08-20
  • 1970-01-01
  • 2013-04-28
相关资源
最近更新 更多