《继承与多态》相关知识
1.运行 TestInherits.java 示例,观察输出,注意总结父类与子类之间构造方法的调用关系修改Parent构造方法的代码,显式调用GrandParent的另一个构造函数,注意这句调用代码是否是第一句,影响重大!
TestInherits.java 的内容如下
package h2; 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(); } }
(1)运行结果截图
a.对原程序不做修改
b.将super语句成为parent类构造函数第一句的时候
c.将super语句成为parent类构造函数第三句的时候
运行出错
(2)结论
当调用子类的无参构造函数时也会调用基类的无参构造函数
通过 super 调用基类构造方法,必须是子类构造方法中的第一个语句。
3.不可变的“类”有何用?
可以方便和安全地用于多线程环境中,
访问它们可以不用加锁,因而能提供较高的性能。
4.为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来?
构造函数的作用是初始化,而如果父类的成员没有被初始化,那么子类也无法使用。所以只能先调用父类的构造方法,再调用子类的构造方法。
5.参看ExplorationJDKSource.java示例
此示例中定义了一个类A,它没有任何成员:
class A { }
示例直接输出这个类所创建的对象
public static void main(String[] args) {
System.out.println(new A());
}
(1)运行截图
(2)探索之路
a.反汇编
b.阅读字节码指令,弄明白println()那条语句到底调用了什么?
c.依据第(2)得到的结论,使用Eclipse打开JDK源码,查看真正被执行的代码是什么
我通过println的源代码找到了valueOf的源代码
然后找到了toString方法的源代码
(3)结论
当调用输出的方法的术后他的参数会默认调用toString这个方法,所以会输出上面的结果。
5.方法覆盖要求子类与父类的方法一模一样,否则就是方法重载(overload)!
请自行编写代码测试以下特性(动手动脑):
在子类中,若要调用父类中被覆盖的方法,可以使用super关键字。
(1)代码
package h4; public class testOverride { public static void main(String[] args) { child a=new child(); a.test(); } } class parent{ public void test() { System.out.println("haha"); } } class child extends parent{ public void test() { super.test(); } }
(2)结果截图
6.现在有三个类:
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;
先进行自我判断,得出结论后,运行TestCast.java实例代码,看看你的判断是否正确。
答:第二句和第四句会编译错误,因为只能有子类给父类赋值,而父类不能给子类赋值,由父类继承出来的两个子类也不能互相赋值,要想赋值必须进行强制类型转换。
7.运行以下测试代码
左边的程序运行结果是什么?
你如何解释会得到这样的输出?
计算机是不会出错的,之所以得到这样的运行结果也是有原因的,那么从这些运行结果中,你能总结出Java的哪些语法特性?
(1)运行结果截图
(2)总结当一个子类和一个父类具有相同的数据成员时,如果把子类对象赋值给父类对象,那么父类对象在进行函数调用时将调用子类的函数。