OOP使用子类的实例初始化实例变量

时间:2013-02-14 10:47:53

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

我正在尝试在我的班级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异常。我该如何解决这个问题?

3 个答案:

答案 0 :(得分: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模式的更好解决方案是使用接口。这消除了构造函数问题,还允许从nextNode中删除不需要的prevNodeNullNode变量。

界面示例:

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;
    }
} 

答案 1 :(得分:0)

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

在您的代码中,有一些更糟糕的事情会导致StackoverflowException,因为superclass会创建一个default constructor subclass的对象,而superclass会调用默认值{{1}}的构造函数,它将无限期地运行,直到程序崩溃。

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

答案 2 :(得分:0)

试试这个

    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)...你不能直接调用它