public class HelloWorld{
public static void main(String []args){
Ball b=new Ball();
System.out.println(b.getName());
}
}
class Shape{
private String name;
Shape(){
name="Shape";
}
public String getName(){
return name;
}
}
class Ball extends Shape{
private String name;
public Ball(){
name="Ball";
}
}
为什么我输出为:" Shape"而不是" Ball"?
即使我改变了
,我也会得到相同的结果private String name;
到
public String name;
在Shape
和Ball
类中。
答案 0 :(得分:3)
Ball对象中有两个name
字段 - 一个在Ball
类中定义,另一个在Shape
类中定义。
在子类中创建具有相同名称的字段时,您需要hide父类字段。尽量避免在代码中使用它。通常,您仍然可以使用超级关键字(例如super.name
)访问父字段,但由于您的字段是私密的,因此无法执行此操作。
方法Shape#getName
从其类中返回字段name
。 Java中的字段不会覆盖像方法那样的父字段,因此Shape.name
不会被Ball.name
替换。
查看此代码以了解参考类型如何确定要使用的字段
Ball ball = new Ball();
println ball.name; // prints Ball, because reference type if Ball
Shape shape = ball; // this is same ball object
println shape.name; // prints Shape, because reference type is Shape
println ball.getName(); // prints Shape - getter in Shape class can only see Shape fields
如果你在Ball
课程中添加了getter,那么方法调用将始终返回' Ball'
println ball.getName(); // will print Ball
println shape.getName(); // will print Ball
答案 1 :(得分:1)
对于字段,没有神奇的覆盖名称。如果类中有一个字段,而子类中有一个同名字段,则有两个不同的字段。
Shape.name
和Ball.name
是完全独立的实体。如果您设置了两个字段public
,则会获得:
Shape s = new Ball();
s.getName(); // => returns "shape"
s.name // yields "shape", because you are accessing a class of type `Shape`.
((Ball)s).name // yields "ball", because you are accessing a class of type `Ball`
此时Ball
实际上有两个不同的name
字段:从Shape
继承的字段和在Ball
类本身中声明的字段。
但是,如果您在name
内访问Ball
,则会获得第一个由符号查找规则确定的Ball.name
。如果Shape.name
为protected
或public
,则super.name
可以使用Shape
。请再次注意:有两个单独的名称字段,每个类一个。它们碰巧具有相同的字段名称,但在其他方面完全分开。
相同的查找规则也适用于Shape.getName()
:编译name
时,它会尝试在编译时找到名为Shape
的字段并使用找到一个,这是目前唯一可用的一个:Shape.name
中的一个。查找是静态的。
但是,如果Ball
是私有的,则无法直接从computed_val = ...
constant_val = tf.constant(37.0)
pred = tf.less(computed_val, constant_val) # N.B. Types of the two args must match
类访问它。
答案 2 :(得分:0)
在Java中,所有继承都从超类传递到子类,包括实例变量和方法。
意思是,如果你想用“子类参数”“调用超类方法”,你只需在子类中创建一个对象并调用你的方法。
因为名为getName()
的唯一方法位于你的超类中,所以当调用方法getName()
时,首先在子类中搜索子类,而不是它在超类中搜索。
为此,您有:Shape
而不是Ball
:
答案 3 :(得分:0)
当你创建新球时,在球构造函数中,隐式执行的第一件事是超级构造函数,没有参数。这意味着执行形状构造函数设置name =" shape"。然后,由于getName方法没有重载,你得到了"形状"值。