需要java继承设计技巧
我有一个抽象超类和几个派生类。需要java继承设计技巧,java,inheritance,Java,Inheritance,我有一个抽象超类和几个派生类。 我想创建一个方法 createNew() 在派生类上调用时,它将创建派生类的一个新实例及其所有成员的智能复制。 所有对创建非常重要的成员都在抽象类中,因此代码应该相同。 我可以在超类中编写createNew()的实现吗 诸如此类 SonA sonA2 = sonA1.createNew() SonB sonB2 = sonB1.createNew() abs超类应该执行此实现,因为代码相同。 谢谢 创建一个抽象方法,作为createNew方法使
我想创建一个方法
createNew()
在派生类上调用时,它将创建派生类的一个新实例及其所有成员的智能复制。所有对创建非常重要的成员都在抽象类中,因此代码应该相同。
我可以在超类中编写createNew()的实现吗 诸如此类
SonA sonA2 = sonA1.createNew()
SonB sonB2 = sonB1.createNew()
abs超类应该执行此实现,因为代码相同。谢谢 创建一个抽象方法,作为
createNew
方法使用的回调——并在每个子类中实现该方法createNew
可以是公共超类的具体方法,甚至是最终方法。上述抽象方法将返回相应子类的新实例
另一种方法是通过反射找出调用了哪个类
createNew
,并在此基础上创建一个新实例。创建一个抽象方法,作为createNew
方法使用的回调——并在每个子类中实现该方法createNew
可以是公共超类的具体方法,甚至是最终方法。上述抽象方法将返回相应子类的新实例
另一种方法是通过反射找出调用了哪个类
createNew
,并在此基础上创建一个新实例。实现应该在抽象类和具体类之间划分。您可以使用模板方法模式执行此操作:
public abstract class AbstractSon {
protected abstract AbstractSon createNewImpl();
public AbstractSon createNew() {
AbstractSon res = createNewImpl();
res.name = "default name";
return res;
}
}
public class Son1 extends AbstractSon {
protected AbstractSon createNewImpl() {
return new Son1();
}
}
public class Son2 extends AbstractSon {
protected AbstractSon createNewImpl() {
return new Son2();
}
}
您可以以不同的方式划分责任,以获得准确的退货类型:
public abstract class AbstractSon {
protected void prepare(AbstractSon toPrepare) {
toPrepare.name = "default name";
}
}
public class Son1 extends AbstractSon {
public Son1 createNew() {
Son1 res = new Son1();
prepare(res);
return res;
}
}
public class Son2 extends AbstractSon {
public Son2 createNew() {
Son2 res = new Son2();
prepare(res);
return res;
}
}
实现应该分为抽象类和具体类。您可以使用模板方法模式执行此操作:
public abstract class AbstractSon {
protected abstract AbstractSon createNewImpl();
public AbstractSon createNew() {
AbstractSon res = createNewImpl();
res.name = "default name";
return res;
}
}
public class Son1 extends AbstractSon {
protected AbstractSon createNewImpl() {
return new Son1();
}
}
public class Son2 extends AbstractSon {
protected AbstractSon createNewImpl() {
return new Son2();
}
}
您可以以不同的方式划分责任,以获得准确的退货类型:
public abstract class AbstractSon {
protected void prepare(AbstractSon toPrepare) {
toPrepare.name = "default name";
}
}
public class Son1 extends AbstractSon {
public Son1 createNew() {
Son1 res = new Son1();
prepare(res);
return res;
}
}
public class Son2 extends AbstractSon {
public Son2 createNew() {
Son2 res = new Son2();
prepare(res);
return res;
}
}
您可以编写此代码(使用反射:getClass().newInstance()
来获取实际类的实例,而不是定义方法的类),但它存在一些问题。例如,您打算从该方法返回什么
您必须返回超级类型,这意味着您必须为每个调用强制转换
通常的解决方案是定义一个在每个级别上定义的copy()
方法。然后你可以这样做:
class SonA {
SonA createNew() {
SonA result = new SonA();
this.copy( result );
return result;
}
void copy( SonA target ) {
super.copy( target );
// copy my fields to target ...
}
}
您可能还想阅读。您可以编写以下代码(使用反射:getClass().newInstance()
来获取实际类的实例,而不是定义方法的类),但它存在一些问题。例如,您打算从该方法返回什么
您必须返回超级类型,这意味着您必须为每个调用强制转换
通常的解决方案是定义一个在每个级别上定义的copy()
方法。然后你可以这样做:
class SonA {
SonA createNew() {
SonA result = new SonA();
this.copy( result );
return result;
}
void copy( SonA target ) {
super.copy( target );
// copy my fields to target ...
}
}
您可能还想了解。一种可能是将复制分解到一个单独的方法中,并从派生类“
createNew()
”调用该方法:
一种可能是将复制因素分解到一个单独的方法中,并从派生类“
createNew()
”调用该方法:
请注意,在OP的示例中,
SonA.createNew()
和SonB.createNew()
有不同的返回类型。@aix不一定是createNew()
。它将适用于特定的用例,但在更复杂的表达式中它将没有用处。请注意,在OP的示例中,SonA.createNew()
和SonB.createNew()
具有不同的返回类型。@aix不一定是createNew()
。它将适用于特定的用例,但在更复杂的表达式中它将没有用处。这不是真正的c代码吗?你不应该使用“扩展”而不是:?@david99world Oops,你说得对-我最近做了太多的C#。现在已经修好了,谢谢!这不是c代码吗?你不应该使用“扩展”而不是:?@david99world Oops,你说得对-我最近做了太多的C#。现在已经修好了,谢谢!