问题
I use composite classes to group functionalities.
But, the class A (with composite A1), got inherited by B (with composite B1), and a behavior existent at A1 is going to be adapted at B1, but the final a1 must be a B1 instance for this to work.
Obs.: I have ways to make sure the composite instantiation happens properly (only by its composite partner).
Unable to assign a B1 object to a1 final field:
class finalFieldTestFails{
class A1{
A1(A a){}
}
class A{
protected final A1 a1;
A(){
this.a1 = new A1(this);
}
A(A1 a1){
this.a1 = a1;
}
}
class B1 extends A1{
B1(B b){
super(b);
}
}
class B extends A{
//B(){ super.a1=new B1(this); } //FAIL: cant change final value
//B(){super(new B1(this));} //FAIL: cant use 'this' or 'super'
}
}
PS.: the answer shall not involve reflection security tricks if possible.
回答1:
B(){ super.a1=new B1(this); } //FAIL: cant change final value
You can not assign values to already assigned final variables, You can instantiate it within the constructor but not as following.
B(){super(new B1(this));} //FAIL: cant use 'this' or 'super'
You can use this once the instance is created only. Since there is a inheritance tree, it is not completely instantiated, So the compiler complains,
cannot reference this before supertype constructor has been called
回答2:
With this tip, given by @KevinHooke, I found this answer and I came with this code below.
But be aware that this option I chose may cause trouble.
So I ended up using an overriden method to instantiate the "1" kind, letting the super class take care of the assignment.
class finalFieldTestWorks{
class A1{A1(A a){}}
class A{
protected final A1 a1;
A(){
this.a1=new1();
}
protected A1 new1(){return new A1(this);}
}
class B1 extends A1{B1(B b){super(b);}}
class B extends A{
B(){
super();
}
@Override
protected B1 new1(){return new B1(this);}
}
}
PS.: Other tips/workarounds will be appreciated.
来源:https://stackoverflow.com/questions/34822434/composite-inheritance-how-to-assign-a-final-field-at-sub-class-constructor-whic