Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 跳过父构造函数调用祖父母';s_Java_Oop - Fatal编程技术网

Java 跳过父构造函数调用祖父母';s

Java 跳过父构造函数调用祖父母';s,java,oop,Java,Oop,问题是:我有一个抽象类在其构造函数中执行一些工作,还有一组实现抽象类的子类: class AbstractClass { AbstractClass(){ /* useful implementation */ } } class ConcreteClass1 extends AbstractClass { ConcreteClass1(){ super(); /* useful implementation */ } } 然后,需要定制具体类,一个解决方案是扩展具体类:

问题是:我有一个抽象类在其构造函数中执行一些工作,还有一组实现抽象类的子类:

class AbstractClass {
     AbstractClass(){ /* useful implementation */ }
}

class ConcreteClass1 extends AbstractClass {
     ConcreteClass1(){ super(); /* useful implementation */ }
}
然后,需要定制具体类,一个解决方案是扩展具体类:

class CustomizedClass1 extends ConcreteClass1 {
    CustomizedCLass1(){ super(); /* useful implementation */ }
}
但问题是定制类只需要调用抽象类的构造函数,而不需要调用具体类的构造函数

你是如何做到这一点的?更改类关系的建议是有效的

编辑:具体的例子是,ConcreteClass1和CustomizedClass1有不同的数据集(ConcreteData1和CustomizedData1),它是从类的构造函数中的数据库中检索的。问题是,创建CustomizedClass1的实例将检索这两个数据实体


我知道使用简单继承可能不是最好的方法,这就是为什么我指出更改类关系的建议是有效的。

在Java中不能这样做。我经常有学生想这样做,但我从未见过这样的情况,他们真的想这样做

你能举一个具体的例子说明你想做什么以及为什么(你的描述太模糊了),我相信可以找到解决办法:-)

编辑:

对于一个真实世界的示例,您不想这样做(通常)的原因如下:

Animal (constructor makes the eyes)
  |
Mammal (constructor makes the lungs)
  |
Human (constructor sets the language)

如果人类构造器可以跳过哺乳动物构造器,那么你将得到一个没有肺的人类。。。不是很有用。

根据定义,
CustomizedClass1
的任何实例也是
ConcreteClass1
的实例,因此必须将其构造为有效的
ConcreteClass1
实例,然后才能运行
CustomizedClass1
构造函数。否则,如果对其调用
ConcreteClass1
方法,会发生什么?他们会试图对尚未初始化的变量进行操作

如果您认为需要这样做,那么您的设计可能需要重新思考。例如,如果您只需要
ConcreteClass1
中的一些功能,那么可以将该功能分解为
ConcreteClass1
的超类,而
CustomizedClass1
可以扩展该功能,以获得所需的功能


请提供更多关于这些类之间关系的信息。

我觉得这是一个复杂的问题-Java没有很好的能力来处理这些问题

虽然这不是您希望的答案,也不是我自豪地键入的答案,但您可以简单地创建模仿
ConcreteClass1
并使用
AbstractClass
的构造函数的
ConcreteClass2


正如@TofuBeer所说,这不是Java所支持的。这就是为什么一些现代语言(如Scala w/Traits)吸引了热情的开发人员。

为什么不定制一个新创建的
ConcreteClass1
实例,使其行为类似于
AbstractClass
实例(前提是
ConcreteClass1
有相应的保护方法)?即:

此处的设计意图和逻辑可能如下所示:

  • 您希望通过继承获得
    ConcreteClass1
    的(基本)行为,您从中继承(这当然要求设计它时值得继承)

  • 您希望自定义默认情况下由
    ConcreteClass1
    提供的行为。您想要实现的定制通常可以用一些参数来描述。只需将这些参数传递给
    CustomizedClass1
    (可以保护)的特殊方法,并将其命名为
    customize()

  • ConcreteClass1()
    构造函数中执行的定制可以是任意的,具体来说,类实例行为可以“还原”为
    AbstractClass
    ,这可能是您所要求的(如果我没有弄错的话)

  • 调用
    customize_with()
    实际上可能会带来一些开销,这取决于
    ConcreteClass1()
    中的实际操作,在这种情况下,使用重载(可能是受保护的)构造函数肯定是更好的解决方案,除非您希望
    ConcreteClass1
    ”实例能够动态自定义(在这种情况下,
    customize_with()
    ConcreteClass1
    的其余部分应相应设计,即通过合同支持此类行为)

  • 如果语法有问题,请原谅(我没有编写太多Java代码)。

    很简单(但为什么?)

    两点意见: 首先,你不应该像这样“跳过”构造函数。 其次,听起来你真的需要重新思考你的阶级关系

    任何时候你发现自己在想“A延伸B,除了那个……”都是一个很好的时间来进一步审视事物。“延伸”意味着“是A”,这是一种非此即彼的关系:有选择性的行为会增加灰色区域,这会在以后伤害你


    正如人们所说,您可以在ConcreteClass1上提供多个构造函数来执行每种情况下所需的初始化,可能会对它们进行保护,以便它们只能由子类使用。但这里有一个问题:如果有人想要编写需要一些(但不是全部)的定制Class2,该怎么办ConcreteClass1中的功能有哪些?您是否添加了另一个自定义构造函数?

    我想出了一种方法:

    class AbstractClass {
         AbstractClass(){ init(); }
         protected init(){ /* useful implementation */ }
    }
    
    class ConcreteClass1 extends AbstractClass {
         ConcreteClass1(){ init(); /* useful implementation */ }
    }
    
    class CustomizedClass1 extends ConcreteClass1 {
        CustomizedCLass1(){ init(); /* useful implementation */ }
    }
    
    通过这种方式,CustomizedClass1从AbstractClass获得它所需的行为,而无需通过ConcreteClass1初始化


    编辑:哎哟,这不起作用,因为正如一位评论员指出的那样,父级的构造函数是隐式调用的,我认为简单的方法是使用不同的构造函数。

    CustomizedData1是ConcreteData1的子类吗?如果是,那么我建议使用(poss
    class AbstractClass {
       AbstractClass(){ /* useful implementation */ }
    }
    
    class ConcreteClass1 extends AbstractClass {
         ConcreteClass1(){ super(); /* useful implementation */ }
         ConcreteClass1(boolean skip){ super(); }
    }
    class CustomizedClass1 extends ConcreteClass1 {
         CustomizedCLass1(){ super(true); /* useful implementation */ }
    }
    
    class AbstractClass {
         AbstractClass(){ init(); }
         protected init(){ /* useful implementation */ }
    }
    
    class ConcreteClass1 extends AbstractClass {
         ConcreteClass1(){ init(); /* useful implementation */ }
    }
    
    class CustomizedClass1 extends ConcreteClass1 {
        CustomizedCLass1(){ init(); /* useful implementation */ }
    }
    
    
    class ConcreteClass1 extends AbstractClass {
         ConcreteClass1(){
              this(...fetch data as before...);
         }
         ConcreteClass1(ConcreteData1 data){
              myData = data;
              ...
         }
    }
    class CustomizedClass1 extends ConcreteClass1 {
         CustomizedCLass1(){
              super(new CustomizedData1(...));
              ... 
         }
    }
    
    A --> execute() 
    
    B --> executeParent_A() { super.execute(); }
    
    C --> super.executeParent_A();
    
    public class ConcreteClass1 extend AbstractClass
    {
      protected F1 f;
    
      public ConcreteClass1 () {
        super ();
        this.f = new F1();
      }
    }
    
    public ConcreteClass2 extends ConcreteClass1
    {
      public ConcreteClass2 () {
        super (); // I'd like to do super.super() instead (no, you don't)
        this.f = new F2(); // We wasted time with new F1 ();
      }
    }
    
    protected ConcreteClass1 ( F1 f ) {
      super ();
      this.f = f;
    }
    public ConcreteClass1 () {
      this ( new F1 () );
    }
    
    ...
    
    public ConcreteClass2 () {
      super ( new F2 () );
    }