[英]Is there a way to instantiate a child class with parent object in java?
我有一个基类说
class A {
private String name;
private String age;
//setters and getters for same
}
和一个儿童班说
class B extends A {
private String phone;
private String address;
//setters and getters for same
}
现在我有一个A的实例,除此之外我还要在B中设置字段,所以代码就像,
A instanceOfA = gotAFromSomewhere();
B instanceOfB = constructBFrom(instanceOfA);
instanceOfB.setPhone(getPhoneFromSomewhere());
instanceOfB.setAddress(getAddressFromSomewhere());
我可以用给定的A实例化B,但我不想这样做 ,
B constructBFrom(A instanceOfA) {
final B instanceOfB = new B();
instanceOfB.setName(instanceOfA.getName());
instanceOfB.setPhone(instanceOfA.getAge());
return B;
}
相反,我喜欢有一些功能,它具有通用性,足以构造对象,如
public class SomeUtility {
public static <T1, T2> T2 constructFrom(T1 instanceOfT1, Class<T2> className) {
T2 instatnceOfT2 = null;
try {
instatnceOfT2 = className.newInstance();
/*
* Identifies the fields in instanceOfT1 which has same name in T2
* and sets only these fields and leaves the other fields as it is.
*/
} catch (InstantiationException | IllegalAccessException e) {
// handle exception
}
return instatnceOfT2;
}
}
所以我可以用它,
B constructBFrom(A instanceOfA) {
return SomeUtility.constructFrom(instanceOfA, B.class);
}
而且,用例不仅限于父子类,而是这个实用函数可以用于适配器用例。
PS-A和B是我要使用这些类的第三方类,所以我不能在A和B中做任何修改。
好的做法是建立一个“生产” B
实例的工厂类。
public class BFactory {
public B createBFromA(A a) { ... }
}
您必须编写工厂方法的代码,因为没有基于其父类创建子类的标准方法。 它总是具体的,取决于你的类的逻辑。
但是,请考虑它是否真的符合您的需求。 根据其父实例实例化类的智能用例并不多 。 一个很好的例子是ArrayList(Collection c) - 构造一个包含泛型集合(“base”)元素的特定列表(“child”)。
事实上,对于许多情况有避免这种奇特的结构模式。 我知道它可能不适用于您的具体案例,因为您写道您的Base和Child是第三方课程。 但是你的问题标题很通用,所以我认为你可能会发现以下内容很有用。
IBase
接口 Base
实现接口 Child
使用 Base
而不是继承它 Child
实现IBase
并将所有方法从IBase
委托给Base
实例 您的代码将如下所示:
public interface IBase {
String getName();
int getAge();
}
public class Base implements IBase {
private String name;
private int age;
// getters implementing IBase
}
public class Child implements IBase {
// composition:
final private IBase base;
public Child(IBase base) {
this.base = base;
}
// delegation:
public String getName() {
return base.getName();
}
public int getAge() {
return base.getAge();
}
}
在你编辑了你的问题之后,我更加怀疑你想要的是什么是好的。 你的问题看起来更像是一种破坏,违反(或不理解) 基于类的面向对象概念的原则。 对我来说听起来像是来自JavaScript的人,并试图保持JavaScript编程风格,只是使用不同的Java语法,而不是采用不同的语言哲学。
有趣的事实:在基于原型的语言中可以使用父对象实例化子对象,请参阅JavaScript 1.8.5中的示例:
var base = {one: 1, two: 2};
var child = Object.create(base);
child.three = 3;
child.one; // 1
child.two; // 2
child.three; // 3
在我看来,你想避免的方式非常合适。 某处必须有一段这样的代码。
如果您不能将该方法放在目标类中,只需将其放在其他地方(某些工厂)。 你应该另外使你的方法static
。
看看Factory方法模式 。
第二个选项是扩展B并将此方法作为工厂静态方法放在该新类中。 但这个解决方案对我来说似乎更复杂。 然后你可以调用NewB.fromA(A)
。 然后你应该可以使用你的NewB而不是B.
你可以通过反思来做到这一点:
public static void copyFields(Object source, Object target) {
Field[] fieldsSource = source.getClass().getFields();
Field[] fieldsTarget = target.getClass().getFields();
for (Field fieldTarget : fieldsTarget)
{
for (Field fieldSource : fieldsSource)
{
if (fieldTarget.getName().equals(fieldSource.getName()))
{
try
{
fieldTarget.set(target, fieldSource.get(source));
}
catch (SecurityException e)
{
}
catch (IllegalArgumentException e)
{
}
catch (IllegalAccessException e)
{
}
break;
}
}
}
}
*以上代码从在线教程复制
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.