类的成员初始化变量, 其实有若干种.
1. 直接赋值
class A{
Object b=new B();
}
问题: 赋值权力下移子类 (为了抽象)
做法: 子类覆盖父类
如下(然而 , Java 成员变量不存在多态)
class A{
Object b;
}
public SubA extned A{
super.b=new B();// 无法这样使用
}
只能如下
public subA extend A{
//可以这样做
public subA(){
super.b=new B();
}
}
优点:
- 简洁
缺点 :
- 不利于成员变量的读取与写入。
- 若存在相同名称的变量,容易搅混
- 赋值操作需要触发 (没有强制性)
参考:
why instance variable of super class is not overridden in sub class method
针对上述情况, 使用抽象方法显得有优势
- 抽象类
abstratc class AbstractA{
public abstratc B getB();
}
class SubA extend AbstractA{
//实现父类的虚拟方法
public B getB{
return new B;
}
}
//等价于
class SubA extend AbstractA{
final B b=new B();
public B getB{
return b;
}
}
解决了(2)(3)问题,(1)问题中写入并没有解决 (子类的子类无法覆盖, 外部也无法修改. 即 [无状态])。
改良 (使之具有状态)
//(1) 状态(含默认值)
class SubA extend AbstractA{
private B b=new B();
//实现父类的虚拟方法
public B getB{
return b;
}
}
//(2)(不含默认值),DI方式
class SubA extend AbstractA{
private B b;
public void setB{
this.b=b;
}
//实现父类的虚拟方法
public B getB{
return b;
}
public static void main(...){
SubA a=new SubA();
a.setB(new B());
}
}
解决上述问题。
缺点
- 状态等操作仍需手工加入 (子类需要补充的代码有点多)
成员变量 / 参数过多
(资源类)使用bean方式存储, 并让该参数bean进行赋值
(可以分离成资源类,通过set资源类进行链接。 )
class Resource {//Bean或者资源类
B b;
C c;
}
class AbstractA{
public void setResource(Resource re);
}
public class A extends AbstractA{
B b;
C c;
//插入并分解资源
@override
public void setResource(Resource re){
b=re.b;
c=re.c;
}
}
其他解决方案
使用文字或者demo 进行提示子类该如何实现 (用文字指导, 非代码强制)
使用接口代替虚拟函数