Java接口与继承部分的小程序
1.总结父类与子类之间构造方法的调用关系(通过super调用基类构造方法,必须是子类构造方法的第一个语句)
代码示例:
运行结果截图:
修改代码,使调用另一个构造方法
代码为:
运行结果为:
所以,可以通过sperm调用基类构造方法,但super语句必须在第一句。
2.思索:为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来?
构造方法用于对基类的初始化。构造一个对象,先调用其构造方法,来初始化其成员函数和成员变量。子类拥有父的成员变量和成员方法,如果不调用,则从父类继承而来的成员变量和成员方法得不到正确的初始化。
3.一个没有任何成员的类A直接输出会得到A@1c5f743,为什么?真正被执行的代码是什么?
请按照以下步骤进行技术探险:(1)使用javap –c命令反汇编ExplorationJDKSource.class; (2)阅读字节码指令,弄明白println()那条语句到底调用了什么? (3)依据第(2)得到的结论,使用Eclipse打开JDK源码,查看真正被执行的代码是什么
在编译源代码时,当遇到没有父类的类时,编译器会将其指定一个默认的父类(一般为Object),而虚拟机在处理到这个类时,由于这个类已经有一个默认的父类了,main方法实际上调用的是: public void println(Object x),这一方法内部调用了String类的valueOf方法。 valueOf方法内部又调用Object.toString方法: public String toString() { return getClass().getName() +"@" + Integer.toHexString(hashCode()); } hashCode方法是本地方法,由JVM设计者实现: public native int hashCode();所以出现上述结果。
4.验证:
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()); } }
输出结果:
其中Fruit类覆盖了Object类中的toString方法
在“+”运算中,当任何一个对象与一个String对象连接时,会隐式地调用其toString()方法,默认情况下,此方法返回“类名 @ + hashCode”。为了返回有意义的信息,子类可以重写toString()方法。
5.编写代码测试方法覆盖的以下特性:
在子类中,若要调用父类中北覆盖的方法,可以使用super关键字;
覆盖方法的允许访问范围不能小于原方法。
覆盖方法所抛出的异常不能比原方法更多。
声明为final方法不允许覆盖。 例如,Object的getClass()方法不能覆盖。
不能覆盖静态方法
代码示例:
1 public class Test extends Parent { 2 public static void main(String[] args) { 3 Test t=new Test(); 4 t.Parent(); 5 t.Parent1(); 6 t.Child(); 7 } 8 public void Parent(){ //parent方法的重载 9 System.out.println("Child"); 10 } 11 public void Child(){ 12 super.Parent(); //调用父类方法parent 13 14 } 15 } 16 class Parent{ 17 public void Parent(){ 18 System.out.println("Parent "); 19 } 20 public void Parent1(){ 21 System.out.println("Parent1"); 22 } 23 24 }
运行结果: