【问题标题】:Infinite child object type [closed]无限子对象类型
【发布时间】:2018-03-23 22:01:02
【问题描述】:

我需要创建一个父类和子类,但子类可能包含父类,我如何在 java 中做到这一点?

例如:

ParentClass {
  ChildClass childClass;
}

ChildClass {
  ParentClass parentClass;
}

这可能吗?如果可能的话,Java 中的术语是什么?

【问题讨论】:

  • 您的代码没有显示任何继承 - 还有对 ParentClass 的引用有什么问题?
  • 你这么说,但问题出在哪里?
  • 编译运行了吗?它做了你想要的吗?您将如何使用这些对象?一个更清晰的问题和一个真实的例子会更容易回答。
  • 这不是问题。你真的尝试过这样做吗?

标签: java algorithm


【解决方案1】:

这是可能的,因为字段为空,创建一个实例永远不会创建它的其他类实例。

以下内容将在运行时爆炸:

class ParentClass {
  ChildClass childClass = new ChildClass();
}

class ChildClass {
  ParentClass parentClass = new ParentClass();
}

new ChildClass();

下面也会爆炸。

class ParentClass {
  ChildClass childClass = new ChildClass();
}

class ChildClass extends ParentClass {
}

new ChildClass();

或者简单地说:

class ParentClass {
  ParentClass parentClass = new ParentClass();
}

new ParentClass();

【讨论】:

    【解决方案2】:

    这个问题根本不涉及继承。只是“孩子”和“父母”名称的使用令人困惑。

    您正在创建循环依赖,其中子类有一个引用父类的字段,而父类有一个引用子类的字段。

    这个问题已经有了答案here。答案是您使用工厂在构造函数中引用您的字段:

    class Parent {
        Child child;
    
        Parent(Child child) {
            this.child = child;
        }
    }
    
    abstract class Child {
        Parent parent;
    
        Child() {
            this.parent = constructParent();
        }
    
        protected abstract Parent constructParent();
    }
    
    public class Main {
        public static void main(String []args){
            new Child(){
                protected Parent constructParent(){
                    return new Parent(this);
                }
            };
        }
    }
    

    要么你以后使用 setter 影响你的领域:

    class Parent {
        Child child;
    
        Parent() {}
    
        void setChild(Child child) {
            this.child = child;
        }
    }
    
    class Child {
        Parent parent;
    
        Child(){}
    
        void setParent(Parent parent) {
            this.parent = parent;
        }
    }
    
    public class Main {
        public static void main(String []args){
             Parent parent = new Parent();
             Child chill = new BChild();
    
             parent.setChild(child);
             child.setParent(parent);
        }
    }
    

    【讨论】:

      【解决方案3】:

      是的,这是可能的。您正在寻找术语 Composition has-a 关系。

      【讨论】:

        【解决方案4】:

        您很可能将继承与组合混淆了。

        在继承中,子类父类(以及更多)。它是使用extends 关键字生成的,如下代码所示:

        class Dog extends Animal { /*...*/ }
        

        Dog 是一个Animal,因此将继承父类的公共和受保护方法,例如feed()breed() 等。它可以定义特定于子类的其他方法,例如作为bark()

        这个方向必须是单向的,如果一个类A扩展了一个类B,那么类B不能扩展类A(他们的定义会递归成一个无限循环:“什么是Dog?嗯,首先,它是一个Animal;好吧,什么是Animal?首先,它是一个Dog,等等。”)

        在组合中,一个类具有对另一个类的实例的引用。它是通过使用引用其他类实例的字段生成的,例如在以下代码中:

        class Kennel {
            Director director;
            Set<Dog> dogs;
            //...
        }
        

        一个Kennel 有一个Director 和一组Dogs。

        在这种情况下,两个类之间的关系可以是双向的(Dog 可以有一个Kennel 字段)没有任何问题,而且这种关系实际上不是类之间而是实例之间的关系(除非您的字段是static,但我们不要为此烦恼)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多