class Parent {
String st = "external";
void print() {
System.out.println(st);
System.out.println(this.st);
}
}
class Child extends Parent {
String st = "inner";
}
public static void main(String[] args) {
new Child().print(); // shows "external"
}
为什么调用子类的print()
不显示字符串" inner"?
答案 0 :(得分:2)
为什么在子类上调用的print()不显示字符串 - “内部”?
因为无法覆盖成员变量。类st
中的成员变量Child
不会覆盖类st
中的成员变量Parent
。两个成员变量是两个独立的变量,它们碰巧具有相同的名称。
类Parent
中的方法看到类st
中定义的成员变量Parent
,而不是类Child
中的那个,即使对象确实是类Child
的实例。
只能覆盖方法。
Oracle Java教程中的更多信息:Hiding Fields(感谢@JonK)。
答案 1 :(得分:1)
正如其他人提到的那样,隐藏了st
类的字段Parent
。如果你想要它打印“内部”,只需添加一个。
将Child
课改为:
class Child extends Parent {
public Child() {
st = "inner";
}
}
这样,来自st
类的Parent
的值被覆盖!
答案 2 :(得分:0)
为什么在子类上调用的print()不显示字符串 - "内部" ?
为什么要这样?你正在调用只在父类中覆盖的方法print()
,在父类中,st只保存值" 外部"
答案 3 :(得分:0)
其他答案涵盖了您注意到的行为的原因,因此我不会涉及到这一点。就你的问题的解决方案而言,有一些值得一提(忽略了诸如反射和子类投射之类的东西;技术上的解决方案,但是很差的解决方案。)
如上所述,只需在Child:
中设置参数即可class Child extends Parent{
public Child() {
st = "inner";
}
}
也可以覆盖print()
方法(因为,如上所述,只能覆盖方法)。 Child
会变成以下内容:
class Child extends Parent{
...
@Override
void print() {
// Child-specific implementation here.
}
}
这将导致Child
个对象使用其print方法代替Parent
的方法。
另一种选择是使用策略模式。请考虑以下事项:
public interface Strategy {
String getString();
}
public class ParentStrategy implements Strategy {
@Override
public String getString() {
return "external";
}
}
public class ChildStrategy implements Strategy {
@Override
public String getString() {
return "inner";
}
}
从这里,您需要做的就是更改您的Parent对象,使其默认为ParentStrategy,提供更改策略的访问者,更改其print方法以使用其Strategy对象的getString()方法,以及更改策略在Child中使用ChildStrategy:
class Parent{
Strategy strat = new ParentStrategy();
void setStrategy(Strategy s) {
strat = s;
}
void print() {
System.out.println(strat.getString());
}
}
class Child extends Parent{
public Child() {
super();
setStrategy(new ChildStrategy());
}
}
在实际应用中,此模式是制作灵活应用程序的基本工具。