ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

继承和多态

2022-08-08 19:04:36  阅读:447  来源: 互联网

标签:setValue 继承 子类 多态 value getValue 构造 父类


0 概念

.1 继承 关键字:extends 关系:is-a

  • 概念:手机和iPhone就像是继承关系,iPhone is a mobile phone。
  • 格式:public class Iphone extends Phone{}
  • 子类的特点:可以有父类的内容,还可以有自己特有的内容。Iphone可以有电话都有的打电话发信息的功能,还有面部解锁、全景拍照等自己的功能。
  • Java中只支持单继承

.2 super关键字和this关键字

  • this:代表对本类对象的引用
  • super:代表对父类对象的引用

.3 继承中的构造方法-ref:为何需要无参构造?

  1. 子类中所有构造方法默认都会访问父类中 无参的构造方法

因为子类会继承父类中的数据,还可能使用父类中的数据。 因此子类初始化之前,一定要先完成父类数据的初始化。所以每一个子类构造方法的第一句都是super()。根据关键词的意思,该语句的意思就是引用父类的无参构造。若父类没有无参构造,则编译时会发生错误。
如图所示,A类的有参构造override默认的无参构造,则不具备无参构造。而B想要调用super()是会编译报错的,这也是一个类需要无参构造的原因。(虽然也可以通过super父类有参构造,但是不推荐)

.3 多态

  1. 什么叫多态?
    有继承或实现关系+此方法重写+有父类引用指向子类对象这三个条件是多态的前提。BTW,父类引用指向子类对象的行为又叫做向上转型
  2. 多态中成员访问的特点
  • 成员变量,编译看左边,执行看左边
  • 成员方法,编译看左边,执行看右边
    成员方法有重写,成员变量没有,所以不一样。
    例子:
    父类A:成员变量a,一个无参构造,一个有参构造,一个get方法。

    子类B:成员变量a,一个重写了父类的无参构造,一个自己仅有的方法onlyB。

    测试一下多态的结果:

子类构造执行肯定先执行父类的构造。若没有写super,则默认使用父类的无参构造。

1 例子

通过一个例子加深对继承和多态的理解。

class Test {
    public static void main(String[] args) {
        System.out.println(new B().getValue());
    }
    static class A {
        protected int value;
        public A (int v) {
            setValue(v);
        }
        public void setValue(int value) {
            this.value= value;
        }
        public int getValue() {
            try {
                value ++;
                return value;
            } finally {
                this.setValue(value);
                System.out.println(value);
            }
        }
    }
    static class B extends A {
        public B () {
            super(5);
            setValue(getValue()- 3);
        }
        public void setValue(int value) {
            super.setValue(2 * value);
        }
    }
}

输出的结果应该是什么?

2 分析

我把两个类并排放在一起,这样看起来方便一点。

  1. 进入主函数,分析程序执行的顺序。 第一模块,执行new B(),创建对象。 第二模块,执行B.getValue(),调用对象的方法。第三模块,sout输出语句,输出函数的返回值。按照顺序进行分析。
  2. 第一模块:new B(),创建类B的对象。
    2.1 进入B的构造。先执行super(5).已知B类继承A类,所以要先完成父类A的构造。B类继承了A类的有参构造super(A),传递了参数v=5.
    2.2 进入A的构造,A的构造调用了方法setValue(5)。而子类B重写了父类A的该方法,调用B的setValue。
    2.3 进入B的setValue(5),方法体内指向父类的setValue方法,参数v = 2 * value = 10
    2.4 进入A的setValue(10),this.value = value = 10。B实例的value=10.
    2.5 A的构造执行完毕。
    2.6 再执行setValue(getValue()- 3); 先执行getValue()。B没有重写该方法,调用父类的getValue()
    2.7 进入B的getValue()。执行try内语句。B.value++,B.value=11,return 11.getValue()返回11.
    2.8 就算return,finally还是会执行。执行finally内语句。调用setValue(11),同理,进入子类重写的setValue(11).进入B的setValue(11),引用父类的setValue(11*2),进入A的setValue(22),此时B.value=22.输出22,而前面11已经作为函数的返回值返回了。
    2.9 再执行setValue(getValue()-3)即setValue(11-3)=setValue(8)。
    2.10 进入B的setValue(8),super.setValue(16),进入A的setValue(16),B.value=16。
    2.11 B的构造执行完毕。
  3. 第二模块,实例B.getValue(),继承A的getValue()
    3.1 进入try内。value++,B.value=17。return value。返回值17.
    3.2 进入finally内。this.setValue(17),调用B的setValue(17),进入A的setValue(17 * 2),B.value=34。输出34.
  4. 第三模块,输出返回值。之前已经返回了17,所以输出17.

所以输出的结果应该是22 34 17。

标签:setValue,继承,子类,多态,value,getValue,构造,父类
来源: https://www.cnblogs.com/80sVolxxxx/p/16562915.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有