[英]Non overridden method doesn't show subclass field
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"
}
Why does print()
called on subclass not show the string "inner"? 为什么在子类上调用的
print()
不显示字符串“inner”?
why print() called on subclass doesn't show string - "inner" ?
为什么print()调用子类不显示字符串 - “内部”?
Because member variables cannot be overridden. 因为成员变量无法被覆盖。 The member variable
st
in class Child
does not override the member variable st
in class Parent
. 成员变量
st
类Child
不会覆盖成员变量st
类Parent
。 The two member variables are two separate variables, which happen to have the same name. 两个成员变量是两个独立的变量,它们碰巧具有相同的名称。
The methods in class Parent
see the member variable st
that is defined in class Parent
, and not the one in class Child
, even if the object is really an instance of class Child
. 在类中的方法
Parent
看到成员变量st
是在类中定义的Parent
,而不是一个在课堂上Child
,即使对象是真正的类的实例Child
。
Only methods can be overridden. 只能覆盖方法。
More information in Oracle's Java Tutorials: Hiding Fields (thanks @JonK). Oracle Java教程中的更多信息: 隐藏字段 (感谢@JonK)。
As the others mentioned the field st
of the Parent
class is hidden. 正如其他人提到的那样,隐藏了
Parent
类的字段st
。 Just an addition if you want it to print "inner". 如果你想要它打印“内部”,只是一个补充。
Change Child
class to this: 将
Child
类更改为:
class Child extends Parent {
public Child() {
st = "inner";
}
}
This way the value of st
from the Parent
class is overriden! 这样,来自
Parent
类的st
的值被覆盖!
why print() called on subclass doesn't show string - "inner" ?
为什么print()调用子类不显示字符串 - “内部”?
why should it? 为什么要这样? you are calling the method
print()
that is only override in the parent class up there in the parent class st is only holding the value " external " 你正在调用方法
print()
,它只是在父类中覆盖,在父类中,st只保存值“ external ”
The other answers cover why the behavior you notice is expected, so I won't touch on that. 其他答案涵盖了您注意到的行为的原因,因此我不会涉及到这一点。 In terms of a solution to your problem, there are a few worth mention (neglecting things like reflection and subclass casting; technically solutions, but poor ones).
就你的问题的解决方案而言,有一些值得一提(忽略了诸如反射和子类投射之类的东西;技术上的解决方案,但是糟糕的解决方案)。
As Will mentioned, can simply set the parameter in Child: 如上所述,可以简单地在Child中设置参数:
class Child extends Parent{
public Child() {
st = "inner";
}
}
Can also override the print()
method (because, as mentioned, only methods can be overridden). 也可以覆盖
print()
方法(因为,如上所述,只能覆盖方法)。 Child
would become something along the lines of: Child
会成为:
class Child extends Parent{
...
@Override
void print() {
// Child-specific implementation here.
}
}
This will result in Child
objects using their print method in place of Parent
's method. 这将导致
Child
对象使用其print方法代替Parent
的方法。
Another option is to use Strategy pattern. 另一种选择是使用策略模式。 Consider the following:
考虑以下:
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";
}
}
From here, all you need to do is change your Parent object so that it defaults to ParentStrategy, provide accessors to change the Strategy, change its print method to use the getString() method of its Strategy object, and change the Strategy in Child to use ChildStrategy: 从这里,您需要做的就是更改您的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());
}
}
In real world applications, this pattern is a fundamental tool to making flexible applications. 在实际应用中,这种模式是制作灵活应用程序的基本工具。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.