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
提前致谢
答案 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; }
}