完成课件中的动手动脑的或需要验证的相关内容。

本文详细解析了Java中父类与子类构造方法的调用关系,解释了为何子类构造方法必须首先调用父类构造方法的原因。并通过示例代码展示了如何在子类中调用父类被覆盖的方法。

 

一.运行 TestInherits.java 示例,观察输出,注意总结父类与子类之间构造方法的调用关系修改Parent构造方法的代码,显式调用GrandParent的另一个构造函数,注意这句调用代码是否是第一句,影响重大!

 

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();

 

 

 

  }

 

 

 

}

 

结论:

 

通过 super 调用基类构造方法,必须是子类构造方法中的第一个语句。

 

 

 

   

二.为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来?

构造函数(constructor)是一种特殊的方法 。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载。构造函数的功能主要用于在类的对象创建时定义初始化的状态。

构造一个对象,先调用其构造方法,来初始化其成员函数和成员变量。
子类拥有父的成员变量和成员方法,如果不调用,则从父类继承而来的成员变量和成员方法得不到正确的初始化。
不能反过来调用也是这个原因,因为父类根本不知道子类有神魔变量而且这样一来子类也得不到初始化的父类变量,导致程序运行出错!

二.请自行编写代码测试以下特性(动手动脑):在子类中,若要调用父类中被覆盖的方法,可以使用super关键字。

  class Father{    //父类

public void shuchu(){

System.out.println("调用父类");

}

}

class Son extends Father{  //子类

public void shuchu){

super.shuchu();

System.out.println("调用子类");

}

}

 

class Override {

   public static void main(String[] args){

   Son a=new Son();

   a.shuchu();

   }

}

四.下列语句哪一个将引起编译错误?为什么?哪一个会引起运行时错误?为什么?

m=d;

d=m;

d=(Dog)m;

d=c;

c=(Cat)m;

先进行自我判断,得出结论后,运行TestCast.java实例代码,看看你的判断是否正确。

d=md=c会编译错误,父类不能直接给子类对象赋值,必须要强制转换,而且两个子类之间没有关系,不能相互赋值。

五.运行以下测试代码

1.   左边的程序运行结果是什么?

1.   你如何解释会得到这样的输出?

   前两个就是正常的调用父类和子类,输出相应的myvalue值,第三个是子类把对象赋值给父类,所以输出父类的值,第四个parent.myValue++;改变的是父类的value值,并没有改变子类的值,((Child)parent).myValue++;改变的是子类的值。

2.   计算机是不会出错的,之所以得到这样的运行结果也是有原因的,那么从这些运行结果中,你能总结出Java的哪些语法特性?

1) 当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。

2)这个特性实际上就是面向对象“多态”特性的具体表现。

3)如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。如果子类方法确实想访问父类中被隐藏的同名字段,可以用super关键字来访问它。

4)如果子类被当作父类使用,则通过子类访问的字段是父类的!

 

转载于:https://www.cnblogs.com/zhmbg/p/7815294.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值