1.动手实验:继承条件下的构造方法调用
代码如下
class Grandparent { public Grandparent() { System.out.println("GrandParent Created."); } public Grandparent(String string) { System.out.println("GrandParent Created.String:" + string); } } class Parent extends Grandparent { public Parent() { //super("Hello.Grandparent."); System.out.println("Parent Created"); // super("Hello.Grandparent."); } } class Child extends Parent { public Child() { System.out.println("Child Created"); } } public class TestInherits { public static void main(String args[]) { Child c = new Child(); } }
ok,我们来看一看输出结果:
GrandParent Created.
Parent Created
Child Created
注意顺序:是先祖父,再父亲最后是儿子。也就是调用的时候会优先调用其父类的构造函数,儿子类的要排到后面了。而且看程序里面有两个super语句,super语句是专门用来调用前一个父类的方法,实验可以得到,super的构造语句必须放在前面。
2.为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来?
答:构造一个对象,先调用其构造方法,来初始化其成员函数和成员变量。子类拥有父的成员变量和成员方法,如果不调用,则从父类继承而来的成员变量和成员方法得不到正确的初始化。不能反过来调用也是这个原因.
3.神奇的“+”号
public class Fruit { public String toString() { return "Fruit toString."; } public static void main(String args[]) { Fruit f=new Fruit(); System.out.println("f="+f); // System.out.println("f="+f.toString()); } }
结果是:f=Fruit toString.
答:在“+”运算中,当任何一个对象与一个String对象,连接时,会隐式地调用其toString()方法,默认情况下,此方法返回“类名 @ + hashCode”。为了返回有意义的信息,子类可以重写toString()方法。
4.
请自行编写代码测试以下特性(动手动脑): 在子类中,若要调用父类中被覆盖的方法,可以使用super关键字:
class Parent { public void show() { System.out.println("123"); } } class Child extends Parent { public void show() { super.show(); System.out.println("321"); } } public class asd { public static void main(String [] args) { Child c = new Child(); c.show(); }
输出结果是:
123
321
因为super方法在子类覆盖方法类使用,只有这样才能调用父类中被覆盖的方法,并且super语句放在子类覆盖方法的话位置就没有要求了。
5.现在有三个类: class Mammal{} class Dog extends Mammal {} class Cat extends Mammal{}
针对每个类定义三个变量并进行初始化 Mammal m=null ; Dog d=new Dog(); Cat c=new Cat();
下列语句哪一个将引起编译错误?为什么?哪一个会引起运行时错误?为什么?
m=d; d=m; d=(Dog)m; d=c; c=(Cat)m;