1.自行编写代码验证在子类中,若要调用父类中被覆盖的方法,可以使用super关键字
class animal { public void tedian(int a,int b) { System.out.println("动物函数:"+a+"*"+b+"="+a*b); } } class bird extends animal { public void tedian(int a,int b) { super.tedian(a+1,b+1); System.out.println("鸟函数:"+a+"*"+b+"="+a*b); } } public class Test { public static void main(String[] args) { bird A=new bird(); A.tedian(1,2); } }
若在子类中未加super,则只显示鸟函数。
2.下列语句哪一个将引起编译错误?为什么?哪一个会引起运行时错误?为什么?m=d;d=m; d=(Dog)m; d=c;c=(Cat)m;先进行自我判断,得出结论后,运行TestCast.java实例代码,看看你的判断是否正确。
第一个正确,第二个不正确,第三个正确,第四个不正确,第五个正确。
class Mammal{} class Dog extends Mammal {} class Cat extends Mammal{} public class TestCast { public static void main(String args[]) { Mammal m; Dog d=new Dog(); Cat c=new Cat(); m=d; //d=m; d=(Dog)m; //d=c; //c=(Cat)m; } }
子类对象可以赋值给父类,而父类赋值给子类必须经过子类强制转换,子类之间不能互相赋值。
3.
public class ParentChildTest { public static void main(String[] args) { Parent parent=new Parent(); parent.printValue(); Child child=new Child(); child.printValue(); parent=child; parent.printValue(); parent.myValue++; parent.printValue(); ((Child)parent).myValue++; parent.printValue(); } } class Parent{ public int myValue=100; public void printValue() { System.out.println("Parent.printValue(),myValue="+myValue); } } class Child extends Parent{ public int myValue=200; public void printValue() { System.out.println("Child.printValue(),myValue="+myValue); } }
猜测结果:第一行为Parent.printValue(),myValue=100 第二行为Child.printValue(),myValue=200 第三行为Child.printValue(),myValue=200 第四行为Child.printValue(),myValue=201 第五行为Child.printValue(),myValue=201
运行结果:
总结:子类对象可以赋值给父类,而父类赋值给子类必须经过子类强制转换。子类能覆盖父类,但是父类中的变量的值是不改变的,访问父类中的变量时可用super来访问。父类被覆盖时,对父类中的变量进行操作时,父类中的变量改变,但输出时仍输出子类的变量。(child)Parent.myValue++,这时改变的是覆盖父类的子类。当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。这个特性实际上就是面向对象“多态”特性的具体表现。如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。如果子类方法确实想访问父类中被隐藏的同名字段,可以用super关键字来访问它。如果子类被当作父类使用,则通过子类访问的字段是父类的!