Java 使用相互引用的最终成员对两个类进行子类化
假设我有两个这样的班Java 使用相互引用的最终成员对两个类进行子类化,java,subclass,Java,Subclass,假设我有两个这样的班 公共类Foo { 受保护的儿童; 公共食物( { child=新条(此条); } } 公共类酒吧 { 受保护的最终Foo父母; 公共酒吧(Foo家长) { this.parent=parent; } } 我想创建一个子类Foo,Foo2,它的子类是Bar2,它是Bar的子类。我可以这样做: 公共类Foo { 受保护的儿童; 公共食物( { child=新的makeChild(); } 受保护的条makeChild() { 返回新条(本条); } } 公共类Foo2扩展了F
公共类Foo
{
受保护的儿童;
公共食物(
{
child=新条(此条);
}
}
公共类酒吧
{
受保护的最终Foo父母;
公共酒吧(Foo家长)
{
this.parent=parent;
}
}
我想创建一个子类Foo
,Foo2
,它的子类是Bar2
,它是Bar
的子类。我可以这样做:
公共类Foo
{
受保护的儿童;
公共食物(
{
child=新的makeChild();
}
受保护的条makeChild()
{
返回新条(本条);
}
}
公共类Foo2扩展了Foo
{
@凌驾
受保护的条makeChild()
{
返回新的Bar2(本);
}
}
然而。但像这样的事情是行不通的:
公共类Foo
{
受保护的儿童;
公共食物(
{
这个(新吧)(这个);;
}
受保护的Foo(Bar-child)
{
这个孩子=孩子;
}
}
因为在调用超类型构造函数之前,newbar(this)
引用了this
我认为有两种方法可以解决这个问题:
1) 我可以将成员设置为私有的和非最终的,然后创建setter,如果已经设置了,就会抛出一个异常,但这看起来很笨拙,而且只能在运行时检测到任何编码问题
2) 我让Foo
构造函数将要使用的Bar
类型的Class
对象作为参数,然后使用反射调用该类的构造函数。然而,这似乎是我正在努力做的事情的重量级
有没有我遗漏的编码技术或设计模式
有没有我遗漏的编码技术或设计模式
我想到了这个模式。只需将参数全部从构造函数中取出,生成构成接口上方类的类型,然后在需要时注入适当的具体类型
Foo接口
interface Foo {
public void setBar(Bar bar);
public Bar getBar();
}
interface Bar {
public void setFoo(Foo foo);
public Foo getFoo();
}
条形接口
interface Foo {
public void setBar(Bar bar);
public Bar getBar();
}
interface Bar {
public void setFoo(Foo foo);
public Foo getFoo();
}
我一直在考虑使用或类似的方法进一步解耦并自动执行注入。其中一个选择是为初始化创建单独的函数,并在子类ctor中调用init方法: e、 g 当然,它假设Foo和Bar是耦合的,依赖Foo来实例化Bar是合理的。但是,在大多数情况下,您应该考虑通过DI框架向Foo注入条。
在评论中,您提到了最终报告的必要性 虽然在VAR成员现在是私有的情况下,我不认为这是一个大问题,但是这里有另一种方式(实际上类似于上面描述的),如果初始化工作和你的问题一样简单:
class Foo {
protected final Bar child;
public Foo() {
this.child = new Bar(this);
}
}
class Foo2 {
public Foo2() {
this.child = new Bar2(this);
}
}
我还没有测试过代码,但我相信它应该可以工作:p您的问题是关于循环引用的简单问题
首先,您应该设计类以避免循环引用,原因有很多 接下来,如果您没有选择,那么最好的解决方案是使用“依赖注入”。为什么?这样想:
因此依赖注入可以安全地进行拯救。但是在这种情况下,
子成员不能是final
,因为它不是在构造函数中设置的。哦,我还没有认识到“final”是您的要求之一。然而,鉴于变量现在是私有的,将其作为非最终变量似乎不是那么关键
不起作用,因为它在调用超类型构造函数之前引用了this
。很好,让我更新一下它(尽管我很好奇这有多有用:()这需要将成员设为非final
,然后在setXYZ()
方法在单个对象上被多次调用。@MatthewCline关于final是正确的,但我认为没有必要出现异常,尤其是在自动注入的情况下。“首先,您应该设计类以避免循环引用,原因有很多。”.读了这篇链接文章,然后重新思考,我决定将这两个类合并为一个类。