【问题标题】:OOP Initializing instance variables with instances of child classOOP 使用子类的实例初始化实例变量
【发布时间】:2013-02-14 10:47:52
【问题描述】:

我正在尝试在我的班级 Node 上实现 NullObject 设计模式:

    class Node{
        Node nextNode;
        char key;
        Node prevNode;

        /* 
           Would like to initialize nextNode and prevNode to instance of 
           NullNode, something like this (I know what I am doing is wrong)
        */
        Node() {
            nextNode = new NullNode();
            prevNode = new NullNode();
        }
    }

    class NullNode extends Node {
         ....
    } 

使用此代码,我得到了 StackOverflowError 异常。我该如何解决这个问题?

【问题讨论】:

  • 你听说过super keyord吗?可以调用超级构造器super()。
  • 你所做的在我看来并没有错,你只需要重写 NullNode 中的构造函数以避免无休止的递归。
  • 现在我收到 StackOverflowError 异常
  • @fab 如何覆盖 NullNode 中的构造函数?

标签: java oop design-patterns null-object-pattern


【解决方案1】:

你得到一个 StackOverflow 因为总是调用父构造函数(另见:https://stackoverflow.com/a/527069/664108)。在您的情况下,这会导致无限递归。

为避免这种情况,您必须在 Node 构造函数中添加一个检查,并从 NullNode 构造函数显式调用它:

public class Node
{
    Node nextNode;
    char key;
    Node prevNode;

    Node() {
        Node(true);
    }
    Node(boolean createNullNodes) {
        if (createNullNodes) {
            nextNode = new NullNode();
            prevNode = new NullNode();
        }
    }
}

public class NullNode extends Node
{
    NullNode() {
        super(false);
    }
} 

NullObject 模式的一个更好的解决方案是使用接口。这消除了构造函数问题,还允许从NullNode 中删除不需要的nextNode 和prevNode 变量。

界面示例:

public interface INode
{
    public char getKey();
    public INode getNext();
    public INode getPrev();
    // ...
}

public class Node implements INode
{
    Node nextNode;
    char key;
    Node prevNode;

    Node() {
        nextNode = new NullNode();
        prevNode = new NullNode();
    }
    public char getKey() {
        return key;
    }
    public INode getNext() {
        return nextNode;
    }
    public INode getPrev() {
        return prevNode;
    }
}

public class NullNode implements INode
{
    public char getKey() {
        return null;
    }
    public INode getNext() {
        return this;
    }
    public INode getPrev() {
        return this;
    }
} 

【讨论】:

  • 仍然得到stackoverflow..即使在nullnode中放置了空的构造函数。
  • 对不起,我有一个误解。用替代解决方案更新了答案。
  • 我通过 Node() {Node(true); 尝试了上述解决方案} 和 Node(boolean createNullNodes) {...} 构造函数..但在 Node() {Node(true); } 作为“节点类型的方法节点(布尔)未定义”
【解决方案2】:

通常我们不会在Suerclass 中引用Subclass,这会以某种方式破坏继承关系。

在你的代码中有更糟糕的事情会导致StackoverflowException,因为superclass使用subclass的default constructor创建了一个对象,该对象又调用superclass的默认构造函数,它将无限运行,直到您的程序崩溃。

你可以看到空对象模式的实现here

【讨论】:

    【解决方案3】:

    试试这个

        public clas Node
        {
            Node nextNode;
        char key;
        Node prevNode;
    
        Node() {
            this(true);
        }
        Node(boolean createNullNodes) {
            if (createNullNodes) {
                nextNode = new NullNode();
                prevNode = new NullNode();
            }
    
        }
    }
    
        public class NullNode extends Node
        {
            NullNode() {
                super(false);
            }
        } 
    

    要从另一个构造函数调用一个构造函数,请使用 this(args)... 你不能直接调用它

    【讨论】:

      猜你喜欢
      • 2014-09-14
      • 2016-07-28
      • 1970-01-01
      • 1970-01-01
      • 2010-10-06
      • 2011-06-21
      • 2011-03-18
      • 2010-11-26
      • 1970-01-01
      相关资源
      最近更新 更多