子类在Java中使用哪些数据成员?
为什么我的输出是:“形状”而不是“球” 即使我改变了,我也会得到同样的结果子类在Java中使用哪些数据成员?,java,inheritance,overriding,Java,Inheritance,Overriding,为什么我的输出是:“形状”而不是“球” 即使我改变了,我也会得到同样的结果 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
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
类中。在Java中,所有继承都从超类传递到子类,包括实例变量和方法
也就是说,如果您想用“子类参数”来“调用超类方法”,只需在子类中创建一个对象并调用您的方法
由于名为getName()
的唯一方法位于您的超类中,因此在调用该方法getName()
时,首先在子类中搜索,如果该方法不在子类中,则在超类中搜索。为此,您有:
Shape
而不是Java中的Ball
:,所有继承都从超类传递到子类,包括实例变量和方法
也就是说,如果您想用“子类参数”来“调用超类方法”,只需在子类中创建一个对象并调用您的方法
由于名为getName()
的唯一方法位于您的超类中,因此在调用该方法getName()
时,首先在子类中搜索,如果该方法不在子类中,则在超类中搜索。为此,您有:
Shape
而不是Ball
:Ball对象中有两个name
字段-一个在Ball
类中定义,另一个在Shape
类中定义
在子类中创建具有相同名称的字段时,将创建父类字段。在代码中尽量避免它。通常,您仍然可以使用super关键字访问父字段,如super.name
,但由于您的字段是私有的,因此您不能这样做
方法Shape#getName
从其类返回字段name
。Java中的字段不会像方法那样覆盖父字段,因此Shape.name
无论如何不会被Ball.name
替换
查看此代码以了解引用类型如何确定要使用的字段
public String name;
如果在Ball
类中添加getter,则方法调用将始终返回“Ball”
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对象中有两个
name
字段-一个在Ball
类中定义,另一个在Shape
类中定义
在子类中创建具有相同名称的字段时,将创建父类字段。在代码中尽量避免它。通常,您仍然可以使用super关键字访问父字段,如super.name
,但由于您的字段是私有的,因此您不能这样做
方法Shape#getName
从其类返回字段name
。Java中的字段不会像方法那样覆盖父字段,因此Shape.name
无论如何不会被Ball.name
替换
查看此代码以了解引用类型如何确定要使用的字段
public String name;
如果在Ball
类中添加getter,则方法调用将始终返回“Ball”
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
创建新球时,在球构造函数中隐式执行的第一件事是超级构造函数,没有参数。这意味着通过设置name=“shape”执行形状构造函数。然后,由于getName方法没有重载,因此您得到了“shape”值。当您创建新的球时,在球构造函数中,隐式执行的第一件事是超级构造函数,没有参数。这意味着通过设置name=“shape”执行形状构造函数。然后,由于getName方法没有重载,因此您得到了“shape”值。字段没有名称的神奇覆盖。如果类中有一个字段,子类中有一个同名字段,则有两个不同的字段
Shape.name
和Ball.name
是完全独立的实体。如果将这两个字段设置为公共,则会得到:
println ball.getName(); // will print Ball
println shape.getName(); // will print Ball
此时,Ball
实际上有两个不同的name
字段:它从Shape
继承的字段和在Ball
类本身中声明的字段
但是,如果访问name
内部的Ball
,则会得到由符号查找规则确定的第一个,即Ball.name
。如果Shape.name
受protected
或public
,它将通过super.name
提供。再次注意:有两个单独的名称字段,每个类一个。它们只是碰巧有相同的字段名,但在其他方面是完全分开的
同样的查找规则也适用于Shape
:当编译Shape.getName()
时,它尝试在编译时查找名为name
的字段,并使用它找到的字段,这是目前唯一可用的字段:Shape
中的字段。查找是静态的
但是,如果Shape.name
是私有的,则不能直接从Ball
类访问它。字段没有名称的神奇覆盖。如果类中有一个字段,子类中有一个同名字段,则有两个不同的字段
Shape.name
和Ball.name
是完全独立的实体。如果将这两个字段设置为公共,则会得到:
println ball.getName(); // will print Ball
println shape.getName(); // will print Ball
此时,Ball
实际上有两个不同的name
字段:它从Shape
继承的字段和在Ball
类本身中声明的字段
但是,如果访问name
内部的Ball
,则会得到由符号查找规则确定的第一个,即Ball.name
。如果Shape.name
受protected
或public
,它将通过super.name
提供。再次注意:有两个单独的名称字段,每个类一个。它们只是碰巧有相同的字段名,但在其他方面是完全分开的
同样的查找规则也适用于Shape
:WhenShape.getName()