简体   繁体   English

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

[英]OOP Initializing instance variables with instances of child class

I am trying to implement the NullObject design pattern on my class Node : 我正在尝试在我的类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 {
         ....
    } 

With this code I get a StackOverflowError Exception. 有了这段代码,我得到了StackOverflowError异常。 How can I tackle this issue? 我该如何解决这个问题?

You are getting a StackOverflow because the parent constructor is always called (see also: https://stackoverflow.com/a/527069/664108 ). 之所以得到StackOverflow,是因为总是调用父构造函数(另请参见: https : //stackoverflow.com/a/527069/664108 )。 In your case this results in endless recursion. 在您的情况下,这将导致无限递归。

To avoid that, you will have to add a check in the Node constructor and call it explicitly from the NullNode constructor: 为了避免这种情况,您将必须在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);
    }
} 

A better solution for the NullObject pattern is using interfaces. NullObject模式的更好解决方案是使用接口。 This eliminates the constructor problem and also allows to remove the not needed nextNode and prevNode variables from the NullNode . 这消除了构造函数问题,还允许从NullNode删除不需要的nextNodeprevNode变量。

Example with interface: 接口示例:

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

Normally we do not reference the Subclass in the Suerclass , this somehow breaks the inheritance relation. 通常我们不会在Suerclass引用Subclass ,这会以某种方式破坏继承关系。

In your code there is something even worse that will cause a StackoverflowException because the superclass creates an object with the default constructor of the subclass which in turns calls the default constructor of the superclass and it will go infinitely until your program crashes. 在您的代码中,甚至有更糟糕的情况会导致StackoverflowException因为superclass使用subclassdefault constructor创建了一个对象,该对象又调用了superclass的默认构造函数,并且它将无限循环运行,直到您的程序崩溃为止。

You can see an implementation of the Null Object Pattern here 您可以在此处看到Null对象模式的实现

Try this 尝试这个

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

To call one constructor from another constructor use this(args)... you cannot call it directly 要从另一个构造函数调用一个构造函数,请使用this(args)...您不能直接调用它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM