1.
1 class Grandparent 2 { 3 4 5 public Grandparent() 6 { 7 8 System.out.println("GrandParent Created."); 9 10 } 11 12 13 public Grandparent(String string) 14 { 15 16 System.out.println("GrandParent Created.String:" + string); 17 18 } 19 20 } 21 22 23 24 class Parent extends Grandparent 25 { 26 27 28 public Parent() 29 { 30 31 //super("Hello.Grandparent."); 32 33 System.out.println("Parent Created"); 34 35 //super("Hello.Grandparent."); 36 37 } 38 39 } 40 41 42 43 class Child extends Parent 44 { 45 46 47 public Child() 48 { 49 50 System.out.println("Child Created"); 51 52 } 53 54 } 55 56 57 58 public class TestInherits 59 { 60 61 62 public static void main(String args[]) 63 { 64 65 Child c = new Child(); 66 67 }
结论:
1、子类的构造方法在执行之前,必须先调用父类的构造方法
2、通过 super 调用父类构造方法,super必须是子类构造方法中编写的第一个语句
3、super本身就是调用父类的构造方法,而且可以执行父类被隐藏的成员变量和被覆盖的父类成员方法
思索:为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来?
答:不能,子类拥有父类的成员变量和成员方法,如果不调用父类的构造方法,则从父类继承而来的成员变量和成员方法不能进行初始化。而不能反过来调用原因是,因为父类不能知道子类有什么成员变量和成员方法并且这样做子类不能在父类帮助下完成继承来的成员变量的初始化,导致成员变量无法初始化,程序就会报错,无法执行。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2.
1 public class ExplorationJDKSource { 2 3 /** 4 * @param args 5 */ 6 public static void main(String[] args) { 7 System.out.println(new A()); 8 } 9 10 } 11 12 class A{}
程序中,main方法实际上调用的是: public void println(Object x),这一方法内部调用了String类的valueOf方法。
valueOf方法的内部又调用Object.toString方法
而Object.toString方法的代码是:
public String toString(){
return getClass().getName() +"@" + Integer.toHexString(hashCode());
}
hashCode方法是本地方法,是JVM的设计者实现的: public native int hashCode();
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3.
1 class Mammal{} 2 class Dog extends Mammal {} 3 class Cat extends Mammal{} 4 5 public class TestCast 6 { 7 public static void main(String args[]) 8 { 9 Mammal m; 10 Dog d=new Dog(); 11 Cat c=new Cat(); 12 m=d; 13 //d=m; 14 d=(Dog)m; 15 //d=c; 16 c=(Cat)m; 17 18 } 19 }
d=m错误:不能从Mammal类转换到Dog类;
d=c错误:不能从Cat类转换到Dog类;
c=(Cat)m正确:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------、
4.
1 public class ParentChildTest { 2 public static void main(String[] args) { 3 Parent parent=new Parent(); 4 parent.printValue(); 5 Child child=new Child(); 6 child.printValue(); 7 8 parent=child; 9 parent.printValue(); 10 11 parent.myValue++; 12 parent.printValue(); 13 14 ((Child)parent).myValue++; 15 parent.printValue(); 16 17 } 18 } 19 20 class Parent{ 21 public int myValue=100; 22 public void printValue() { 23 System.out.println("Parent.printValue(),myValue="+myValue); 24 } 25 } 26 class Child extends Parent{ 27 public int myValue=200; 28 public void printValue() { 29 System.out.println("Child.printValue(),myValue="+myValue); 30 } 31 }
原因:
前两行正常输出,父类对象调用父类的方法,子类对象调用子类的方法;
第三行,当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定;
第四行,当parent=child;仅仅是将parent中有的方法用child的方法代替,所以parent.myValue++;而输出的是child的printValue(),而printValue()方法中输出的是child.myValue,所以输出的是child.myValue;
第五行,强制类型转换,++作用在child的myValue,所以输出的也是child的myValue,而不是parent的myValue;
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
6.
在子类中,若要调用父类中被覆盖的方法,可以使用super关键字。
1 class test{ 2 void play() { 3 System.out.println("我是父类test"); 4 } 5 } 6 7 class test11 extends test{ 8 void play() { 9 super.play(); 10 } 11 } 12 public class test1 13 { 14 public static void main(String[] args) { 15 test11 t=new test11(); 16 t.play(); 17 } 18 19 }