从父类构造对象

时间:2011-04-04 18:18:43

标签: java

A扩展B,我可以在A的构造函数中引用B子项吗?

public A(B b)
{
  /*(B)this = b*/
}

如果没有,我如何用B对象构造一个A对象?我的意思是使用Cloneable从JLS(dozer,beanutils等)创建一些其他实例或解决方案。简而言之,A构造函数如何使这个代码运行?

B b = new B("hi");
A a = new A(b);
assertequals(a.getSalute(), "hi");//ok so far

a.setSalute("hola");
assertequals(b.getSalute(), "hola");//A maintains a reference to B

f(a);//prints hola
f(b);//prints hola as well

提前致谢

3 个答案:

答案 0 :(得分:0)

是。 Java不会像C ++那样禁止对具体类的前向引用。

你必须要注意静态类初始化器。

来自DCL12-J. Prevent class initialization cycles

  

根据§12.4,Java语言规范的“类和接口的初始化”[JLS 2005]

     
    

类的初始化包括执行其static初始值设定项和类中声明的static字段(类变量)的初始值设定项。

  
     

换句话说,static字段的存在会触发类的初始化。但是,静态字段可能依赖于类的初始化,可能会创建初始化周期。 Java语言规范还在§8.3.2.1中描述了“类变量的初始化器”[JLS 2005]

     
    

...在运行时,static变量final并且使用编译时常量值初始化的变量首先被初始化。

  
     

此语句可能会产生误导,因为它不适用于使用稍后初始化的static final字段值的实例。将字段声明为static final不足以保证在读取之前将其完全初始化。

答案 1 :(得分:0)

只要你的构造函数被适当地构造,你就可以像你描述的那样在A的构造函数中引用B.

如果A扩展B,则任何A对象都可以被视为B对象,但反之则不然。

为了更好地回答原始问题,从A创建B应该很简单 - 将构造函数中的A更改为B(因为任何A也是B),调用适当的getter方法并将其值分配给由A持有的实例变量。这种类型的构造函数public B(B b)...是一个复制构造函数。如果您决定在构造函数中保留A,那么只需通过调用B从A继承的所有方法来应用所提到的调用/复制/赋值逻辑。

答案 2 :(得分:0)

看起来你正在尝试某种装饰模式。我不是“界面程序”的最大粉丝,因为我认为这是一个过度使用的好建议,但我认为这是一个很好的情况。

interface Wrapable { // replace Wrapable with something more appropriate
   // common methods here?
}

class B implements Wrapable {

}

class A implements Wrappable {
    Wrappable whatThisWraps;

    A(Wrappable w) { whatThisWraps = w; }
}