public class TestCasting{
public static void main(String []args){
Animal a=new Animal("name");
Dog d=new Dog("dogname","yellow");
Cat c=new Cat("catname","blue");
a=new Dog("bigyellow","yellow");
System.out.println(a.name); //输出bigyellow
Dog d1=(Dog)a;
System.out.println(d1.name); //输出null
System.out.println(d1.furColor); //输出 yellow
}
}
class Animal{
public String name;
Animal(String name){
this.name=name;
}
}
class Dog extends Animal{
public String name;
public String furColor;
Dog(String name,String furColor){
super(name);
this.furColor=furColor;
}
}
class Cat extends Animal{
public String name;
public String eyesColor;
Cat(String name,String eyesColor){
super(name);
this.eyesColor=eyesColor;
}
}
这一行:System.out.println(d1.name); //输出null
为什么输出的是null而不是:bigyellow?
最佳答案:Dog d1=(Dog)a;
因为这一句的定义是把父类对象强制转换为子类对象,又因为子类对象有name和furColor两个属性,所以可以去调用,而"bigyellow"已经被赋给了父类的name属性,所以你再调用子类的name属性时就没有了,只能是null.
其实你程序里把子类都又重新定义一个name属性是多余的.
应该这样写.子类不要再定义name属性,而是直接super(name),这样的话,父类和子类都通用一个name属性,就不会出现错误了.而更加符合继承的思想.
其余答案:
1.因为你在调用构造函数的时候调用了父类的构造方法,实际上传入的bigyellow是赋值给了animal接口里面那个name变量,子类Dog的name变量并没有赋值
2首先要明白继承的关系,你每个类里都是用super(name);来进行取值,而super是调用超类(也就是父类)里的东西,你用a对象去点name,肯定能取出,但d1对象是子类的对象,所以取出来为null..
3分析下程序的执行过程如下:
一、首先: Animal a=new Animal("name");
定义一个引用a指向new Animal("name")
二、然后:a=new Dog("bigyellow","yellow");
把引用a指向新的对象new Dog("bigyellow","yellow");,此时调用子类Dog的构造函数,即:
Dog(String name,String furColor){
super(name);
this.furColor=furColor;
},构造函数super(name);,表示把Dog(String name,String furColor)中的形参name传入,并通过super(name);赋值给父类构造函数,即此时的父类中的name的值为bigyellow;
this.furColor=furColor;意思是把子类的furColor赋值为形参furColor,此时子类的furColor值为yellow;
三、Dog d1=(Dog)a,定义一个子类引用a指向a强制转换后的子类对象,
而 System.out.println(d1.name); //输出null
含义是输出子类d1的局部变量name.而此时子类d1的局部变量name并没有赋值,局部变量没有赋值时候,name默认为值为null,故输出null;
而
System.out.println(d1.furColor); //输出 yellow
打印子类d1的局部变量furColor,已经赋值为yellow,故输出yellow