继承的类变量在初始化时会覆盖父类设置的自身值。

huangapple go评论73阅读模式
英文:

Inherited class variables when initialized are overriding own value setted by parent

问题

我在我的应用程序中有类似这样的内容:

public abstract class A {

    public A (){
        init();
    }
    
    protected abstract void init();
}

public class B extends A {

    private String strName = "";

    public B (){
        super();
    }
    
    @Override
    protected void init(){
        strName = "Hello";
    }
}

我正在创建类B的实例。应用程序按以下顺序运行:

1- 构造函数B,调用super

2- 构造函数A,调用init() 函数

3- 在B中重写的init() 将 "Hello" 赋值给 strName 变量

4- 然后初始化类B中的属性,当前值 "Hello" 被初始化值 "" 覆盖;

如果我想要在许多子类中都有一个类似init()的公共方法,并在父类中调用它,以避免在每个子类中重复,同时避免我遇到的问题。正确的结构是什么?或者父类中的init() 函数应该在子类构造函数中在super之后被调用。

英文:

I have in my app something like this:

public abstract class A {

	public A (){
		init();
	}
	
	protected abstract void init();
}

public class B extends A {

	private String strName = "";

	public B (){
		super();
	}
	
    @Override
	protected void init(){
		strName = "Hello";
	}
}

I'm creating an instance of class B. And the app is running this order:

1- Constructor B, calls the super

2- Constructor A, calls init() function

3- Init() overriden in B is assigning "Hello" to strName variable

4- Then the attributes in class B are initialized, and the current value "Hello" is overwritten by the initialize value "";

Which is the correct structure if I want a common method in many childrens like init(), to be called in the parent. To avoid repeating it in every child. And avoiding the issue that I'm having. Or maybe the init() function in the parent should be called in the child constructor below the super.

答案1

得分: 5

你的问题在于 super() 调用了父类构造函数,而父类构造函数又调用了 init()。strName = ""; 语句是在子类构造函数内,在 super() 调用之后运行的。

如果你想要这样设置,strName 应该是父类中的一个 protected 变量。否则,你应该勇敢地在调用 super(); 后的构造函数中手动初始化它。这是最安全和最可预测的做法。

英文:

Your problem here is super() calls the parent constructor, which calls init(). The strName = ""; statement is then run inside the child class constructor after the super() call.

strName should be a protected variable in the parent class if you want to set it up like that. Otherwise, you should just bite the bullet and manually initialize it in the constructor after the call to super(); That's the safest and most predictable way to do this.

huangapple
  • 本文由 发表于 2020年10月14日 22:15:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/64355250.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定