子类继承的方法,为什么输出的却是父类的成员变量?

quiton 2007-08-08 03:15:30
下面这个程序中,输出的结果是:

my name is wangwu and my age is 10
john
21

我的想法是如果要是子类继承了父类的shout()方法,那么输出的应该是子类的name和age的值啊,怎么会是这样的输出结果???



class Person
{
String name = "wangwu";
int age = 10;
public Person()
{
}
public Person(String name, int age)
{
this.name = name;
this.age = age;
}
void shout()
{
System.out.println("my name is " + name +" and my age is " + age);
}
}
public class Student extends Person
{
String major;
String name = "lisi";
int age = 12;
public Student()
{
super();
}

public Student(String name,int age)
{
//super(name,age);
this.name = name;
this.age = age;
}

public static void main(String args [])
{

Student s1 = new Student("john",21);
s1.shout();

System.out.println(s1.name);
System.out.println(s1.age);
}

}


如果将下面程序段:
//super(name,age);
this.name = name;
this.age = age;
改为:
super(name,age);
//this.name = name;
//this.age = age;
程序的输出结果是:
my name is lisi and my age is 21
lisi
12

给我的感觉好像是shout()方法中始终使用的是父类的成员变量name和age,而子类已经继承了父类,为什么在shout()方法中使用的不是父类的成员变量呢?

请明示!!在内存中的状态又是什么样的呢?
...全文
515 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
zygege 2007-08-09
  • 打赏
  • 举报
回复
老大,很简单的问题弄这么多,你没有重载超类里的void shout()方法
超类里打印的是超类的实例变量,你把超类里的这个方法重载一下!
lalakid 2007-08-08
  • 打赏
  • 举报
回复
留个名字
yiyi2007 2007-08-08
  • 打赏
  • 举报
回复
学习了!!!!
解释得真好!!!
zephyr_cc 2007-08-08
  • 打赏
  • 举报
回复
总的来讲,还是关于动态绑定的问题

只有非final或非static或非private的方法才是动态绑定的
成员变量不是动态绑定的,所以shout()在编译时刻就已经决定了他使用的name和age.它们和shout()具有同样的名字空间.
不管谁去调用,Person的shout()所使用的始终是Person类的name和age.

把你的程序Person和Student各加了一个方法f(), 然后在shout()里面调用了f():
class Person
{
String name = "wangwu";
int age = 10;
public Person()
{
}
public Person(String name, int age)
{
this.name = name;
this.age = age;
}
void shout()
{
f();
System.out.println("my name is " + name +" and my age is " + age);
}
void f() {
System.out.println("Person");
}
}
public class Student extends Person
{
String major;
String name = "lisi";
int age = 12;
public Student()
{
super();
}

public Student(String name,int age)
{
//super(name,age);
this.name = name;
this.age = age;
}

void f() {
System.out.println("Student");
}

public static void main(String args [])
{

Student s1 = new Student("john",21);
s1.shout();

System.out.println(s1.name);
System.out.println(s1.age);
}

}

这是结果:
Student
my name is wangwu and my age is 10
john
21
可以看到,shout()方法中调用的是Student的f()方法.

具体一点讲:
用javap把Person.class打开,可以看到方法shout()中有这么几行:
1: invokevirtual #5; //Method f:()V
20: getfield #3; //Field name:Ljava/lang/String;
32: getfield #4; //Field age:I
其操作数所指的常量池为:
const #3 = Field #16.#33; // Person.name:Ljava/lang/String;
const #4 = Field #16.#34; // Person.age:I
const #5 = Method #16.#35; // Person.f:()V
invokevirtual这个指令就是动态绑定的体现,虽然同样也是指向的f()也是Person类的,但是运行时虚拟机会根据实际类型决定f()的调用.
quiton 2007-08-08
  • 打赏
  • 举报
回复
意思就是说父类的shout()方法虽然别子类继承了,但是使用的却是父类的成员方法,而不是子类的成员方法,是这样嘛?
chenyifei211 2007-08-08
  • 打赏
  • 举报
回复
第一种情况:Student s1 = new Student("john",21);将参数john,21传给构造方法public Student(String name,int age)
{
//super(name,age);
this.name = name;
this.age = age;
}在此构造方法中将参数符值给了name and age 故打印的是john,21,因为student 继承person 并没有重写shot()方法,故s1.shout();还是引用父类的方法故会输出my name is wangwu and my age is 10
第二种情况:Student s1 = new Student("john",21);将参数john,21传给构造方法public Student(String name,int age)
{
super(name,age);
//this.name = name;
//this.age = age;
}此构造方法super父类的方法,即public Person(String name, int age)
{
this.name = name;
this.age = age;
}这个时候就把子类里定义的name and age 值传了过去,所以输出的是lisi 12
同样,由于此时子类super父类的方法,并将值john,21传给了父类的name and age ,故shout()显示结果为:my name is john and my age is 21

62,623

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧