zoukankan      html  css  js  c++  java
  • 继承与多态

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

    答:由于子类是继承父类的,所以想用子类创建对象时,必须先创建父类的对象,这样子类才能有父类的属性和方法。在创建对象时如果父类的数据需要进行初始化,那么就需要调用父类的构造函数。不能反过来,因为父类不知道子类有什么属性,而且反过来子类也不能得到父类初始化的变量。

    2.参看ExplorationJDKSource.java示例

    此示例中定义了一个类A,它没有任何成员:

    class A { }

    示例直接输出这个类所创建的对象

           public static void main(String[] args)    {

                  System.out.println(new A());

    }

    我们得到了一个奇特的运行结果:

             A@1c5f743版)

    为什么?

    答:函数实际上是继承了Object类中的toString方法,因此会有结果输出。

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

    答:源代码:

    //信1603班    20163514  周志慧

    package test1_3;

    class Fruit1

    {

       public void show()

       {

       System.out.println("Fruit");

       }

    }

    class Fruit2 extends Fruit1

    {

      

       public void show()

       {

          super.show();

          System.out.println("Pear");

         

       }

      

    }

    public class Test {

     

       public static void main(String[] args) {

          // TODO 自动生成的方法存根

           Fruit2 f=new Fruit2();

           f.show();

                

     

       }

     

    }

    • 4.现在有三个类:

    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;

    答:第二句,第四句会出现运行错误。

       由于Dog和Cat都是继承的Mammal类,Mammal类是Dog类和Cat类的父类,由于基类对象要赋值给子类必须进行强制类型转换,因此第二句会运行错误;两个子类的类型也不一样因此也不能进行赋值语句。

    • 5.运行以下测试代码

    回答问题:

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

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

    3.   计算机是不会出错的,之所以得

                到这样的运行结果也是有原因的,

                那么从这些运行结果中,你能总

                结出Java的哪些语法特性?

    答:1.运行结果:

    Parent.printValue(),myValue=100

    Child.printValue(),myValue=200

    Child.printValue(),myValue=200

    Child.printValue(),myValue=200

    Child.printValue(),myValue=201

    2.

    运行结果解释:

    Parent类中myValue值为100;Child类中myValue值为200;

    因此第一句Parent parent=new Parent();是创建了Parent类的对象parent

          parent.printValue();对象parent调用了printValue函数,由于Parent类中myValue值为100,因此此时myValue值为100;

    第二句Child child=new Child();创建了Child的对象child

          child.printValue();对象parent调用了printValue函数,由于Child类中myValue值为200,因此此时myValue值为200;

    第三局parent=child;是将子类child赋值给基类parent

          parent.printValue();调用的是Child类中的printValue函数,Child类中的myValue值为200,因此此时输出值为200;

    第四句parent.myValue++;parent中已经被child赋值,执行myValue++;

          parent.printValue();由于在第三句中已经将对象child赋值给parent因此此时的操作应该是对于child对象的操作,执行myValue++后myValue值并没有改变,因此输出值为200;

    第五句((Child)parent).myValue++;将对象parent进行强制性转换为Child类,执行的为parent对象的操作;此时myValue值为201;

          parent.printValue();执行myValue++后myValue值依旧为201;

    • 6.请使用javap查看编译器为TestPolymorphism.java生成的字节码指令,然后通过互联网搜索资料,尝试从底层开始理解Java编译器是如何为多态代码生成字节码指令,在程序运行过程中,多态特性又是如何实现的。

    答: 在 java 语言中,多态性体现在两个方面:由方法重载实现的静态多态性(编译时多态)和方法重写实现的动态多态性(运行时多态)。

      (1)编译时多态

        在编译阶段,具体调用哪个被重载的方法,编译器会根据参数的不同来静态确定调用相应的方法。  

      (2)运行时多态

        由于子类继承了父类所有的属性(私有的除外),所以子类对象可以作为父类对象使用。程序

        中凡是使用父类对象的地方,都可以用子类对象来代替。一个对象可以通过引用子类的实例来调用
        子类的方法。

        重写方法的调用原则(为重点):java 运行时系统根据调用该方法的实例,来决定调用哪个方法。

        对子类的一个实例,如果子类重写了父类的方法,则运行时系统调用子类的方法;如果子类继承了
        父类的方法(未重写),则运行时系统调用父类的方法。

  • 相关阅读:
    路飞学城系列:第2章 数据类型&文件操作-学习笔记【2.1-2.34-列表细讲、元组、字符串细讲、字典、集合、二进制与字符编码、16进制、HASH、为何dict字典查询速度快、用py操作文件、file类的其它必用功能等】
    路飞学城系列:第1章 Python基础语法入门-学习笔记(4)-补充【变量的创建、身份运算、空值None、三元运算】
    路飞学城系列:第2章 数据类型&文件操作-练习(3)【模拟登陆-等待优化ing-读写不能同时进行ing】
    路飞学城系列:第2章 数据类型&文件操作-练习(2)【文件操作:全局替换程序】
    路飞学城系列:第2章 数据类型&文件操作-练习(1)【列表index()方法的操作练习】
    路飞学城系列:第1章 Python基础语法入门-作业(1)【双色球选购-中文-自由发挥】
    Java泛型的理解
    LeetCode 力扣 99. 恢复二叉搜索树
    深入理解Java虚拟机---栈,堆,方法区
    java中API补充总结
  • 原文地址:https://www.cnblogs.com/zzh2019979439/p/7810758.html
Copyright © 2011-2022 走看看