Java初始化成员变量的写法

时间:2022-12-12 12:29:49

类的成员初始化变量, 其实有若干种.

1. 直接赋值

class A{
    Object b=new B();
}

然而, 有时候我们不想让该类进行赋值, 想将赋值权力交给子类, 通常我们的想法是让子类覆盖该成员变量 , 如下(Java 成员变量不存在多态)

public SubA extned A{
    super.b=new B();// 无法这样使用
}

只能如下

public subA extend A{

    //可以这样做
    public subA(){
        super.b=new B();
    }
}

优点:

  • 简洁

缺点 :

  1. 不利于成员变量的读取与写入。
  2. 若存在相同名称的变量,容易搅混
  3. 赋值操作需要触发

参考:

why instance variable of super class is not overridden in sub class method

针对上述情况, 使用抽象方法显得有优势

  1. ##### 抽象类
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)种 状态插入移交外部
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;
}

class AbstractA{
    public void setResource(Resource re);
}

public class A extends AbstractA{
    B b;

    //插入并分解资源
    @override
    public void setResource(Resource re){
        b=re.b;
    }  
}

其他解决方案

  • 使用文字或者demo 进行提示子类该如何实现

  • 使用接口代替虚拟函数

初始化位置

使用set方式触发初始化 ,初始化位置有如下

  1. 平台
  2. 构造函数 , 成员变量 等
  3. 每个执行方法的第一行
public abstrac class abstracA{
    A a;

    public methodA(){
        a=initA();
    }

    abstract A initA();
}