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
的其余部分应相应设计,即通过合同支持此类行为)正如人们所说,您可以在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 () );
}