黑马程序员技术交流社区
标题:
调用被子类重写的方法的一些问题
[打印本页]
作者:
dev
时间:
2012-6-28 17:53
标题:
调用被子类重写的方法的一些问题
本帖最后由 翁游龙 于 2012-6-29 16:54 编辑
看书的时候了解到,在访问权限允许的情况下,子类可以调用父类的方法,
但父类不能调用子类的方法,因为父类根本无从知道它将被哪个子类继承,
它的子类将会增加怎样的方法。(这些我都可以理解)
但有一种特殊情况,当子类方法重写了父类方法之后,父类表面上只是调用属于
自己的方法,可实际上是调用子类的方法。关于以下代码有点不明白的地方:
class Animal{
//desc实例变量保存对象toString方法的返回值
private String desc;
public Animal(){
//调用getDesc()方法初始化desc实例变量
this.desc = getDesc();
}
public String getDesc(){
return "Animal";
}
public String toString(){
return desc;
}
}
public class Wolf extends Animal{
private String name;
private double weight;
public Wolf(String name, double weight){
this.name = name;
this.weight = weight;
}
//重写父类的getDesc()方法
@Override
public String getDesc(){
return "Wolf[name=" + name + ",weight=" + weight + "]";
}
public static void main(String[] args){
System.out.println(new Wolf("灰太狼",32.3));
}
}
运行结果为:
Wolf[name=null,weight=0.0]
问题:为什么运行结果name=null,weight=0.0,程序中不是在构造方法中为这两个
属性赋值了吗,
结果为什么不是name=灰太狼,weight=32.2?
这里不是很明白,请
高手指点下。谢谢!
作者:
王硕'
时间:
2012-6-28 18:01
new Wolf("灰太狼",32.3)---->进入子类的构造方法-->调用父类构造方法public Animal()-->父类的构造方法调用getDesc()方法--->非静态的方法是对象的方法,这个getDesc方法是子类对象的 此时子类的构造方法连super()都没运行外,下面的 this.name = name;和this.weight = weight;还没运行到,
对象的成员都有默认值,所以就是那个打印结果。
作者:
黑马刘杰
时间:
2012-6-28 18:06
我也不明白,但是代码改成这样后就可以了
class Animal
{
// desc实例变量保存对象toString方法的返回值
private String desc;
public Animal()
{
// 调用getDesc()方法初始化desc实例变量
this.desc = getDesc();
}
public String getDesc()
{
return "Animal";
}
public String toString()
{
return desc;
}
}
public class Wolf extends Animal
{
private String name;
private double weight;
public Wolf(String name, double weight)
{
this.name = name;
this.weight = weight;
}
// 重写父类的getDesc()方法
@Override
public String getDesc()
{
return "Wolf[name=" + name + ",weight=" + weight + "]";
}
public static void main(String[] args)
{
System.out.println(new Wolf("灰太狼", 32.3).getDesc());
}
}
复制代码
作者:
常佳杰
时间:
2012-6-28 18:06
哥们这句话
new Wolf("灰太狼",32.3)//
意思是调用了Wolf类的构造函数
,
在下边的这段代码中..
public class Wolf extends Animal{
private String name;
private double weight;
public Wolf(String name, double weight){
this.name = name;
this.weight = weight;
}
//重写父类的getDesc()方法
@Override
public String getDesc(){
return "Wolf[name=" + name + ",weight=" + weight + "]";
}
public static void main(String[] args){
System.out.println(new Wolf("灰太狼",32.3));
}
}
是按照顺序执行的,进入入口后new了个Wolf类对象,
进入类中,先是属性的默认初始化,构造代码块初始化..
重点在这:
你后边还有个return语句,它返回的值是默认的初始化值,并且记录下来...
所以在你输出时是默认的初始化值.
.
也就是Wolf[name=null,weight=0.0]
作者:
车风波
时间:
2012-6-28 18:10
这里new Wolf("灰太狼",32.3),先执行父类构造函数:
public Animal(){
//调用getDesc()方法初始化desc实例变量
this.desc = getDesc();
}
构造函数里执行 this.desc = getDesc();的时候因为子类重写了getDesc();,
所以执行子类的getDesc();
此时子类的构造函数还没有执行,子类的name和weight成员变量都是默认值,
所以getDesc();返回Wolf[name=null,weight=0.0]
所以desc就是Wolf[name=null,weight=0.0]
然后再执行子类的构造函数这个时候才会初始化name,
但是desc这个字符串是不会变了。
所以最后输出的是Wolf[name=null,weight=0.0]
作者:
游洪波
时间:
2012-6-28 19:03
class Animal{
//desc实例变量保存对象toString方法的返回值
private String desc;
public Animal(){
//调用getDesc()方法初始化desc实例变量
this.desc = getDesc();
}
public String getDesc(){
return "Animal";
}
public String toString(){
return desc;
}
}
public class Wolf extends Animal{
private String name;
private double weight;
public Wolf(String name, double weight){
this.name = name;
this.weight = weight;
}
//重写父类的getDesc()方法
@Override
public String getDesc(){
return "Wolf[name=" + name + ",weight=" + weight + "]";
}
public static void main(String[] args){
System.out.println(new Wolf("灰太狼",32.3));
}
}
运行的原理是这样的....
1.你用new Wolf("灰太狼",32.3));这句话实例化了Wolf但是因为Wolf extends 了Animal 所以在这里首先执行Animal 的构造方法。。进入第2步
2. public Animal(){
//调用getDesc()方法初始化desc实例变量
this.desc = getDesc();
}
利用getDesc()给desc赋值,然后会调用tostring()输出,因为子类重写了父类的getdesc()方法,但是此时子类的name属性和weight属性都还没有初始化,所以这个时候调用tostring输出的只能是null
作者:
dev
时间:
2012-6-29 16:54
车风波 发表于 2012-6-28 18:10
这里new Wolf("灰太狼",32.3),先执行父类构造函数:
public Animal(){
//调用getDesc() ...
你解释的很好,我明白了,哈哈。谢谢了!
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2