《继承与多态》相关知识

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)总结当一个子类和一个父类具有相同的数据成员时,如果把子类对象赋值给父类对象,那么父类对象在进行函数调用时将调用子类的函数。

 

 

 

原文地址:https://www.cnblogs.com/duowenjia/p/7809277.html