zoukankan      html  css  js  c++  java
  • Java基础12-继承(思想、覆盖、super,子类初始化)

    .1.什么是继承?为什么要继承?

    从字面意思上来看,继承是孩子从父母哪里继承得到的东西,或是徒弟从师傅哪里得到的技能或手艺。java中继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

    还记得我们的DOTA英雄吗?

    DOTA英雄可以攻击和释放技能,所以继承了它特性的天辉和夜魇英雄都可以攻击和释放技能,但天辉和夜魇英雄都可以拥有自己的独特属性和行为(方法)。

    我们看到,无论是天辉还是夜魇英雄都有名字年龄种族和信仰的属性,都有攻击和释放技能的行为,但是天辉独有选举的方式产生领导者,而夜魇凭借的是力量上位,

    那么我们就可以用extends关键字把它写成

    dota英雄就是天辉和夜魇英雄的父类,天辉和夜魇英雄就是dota英雄的子类

    注意:在java中,只允许单继承,也就是说 一个类最多只能显示地继承于一个父类。但是一个类却可以被多个类继承,也就是说一个类可以拥有多个子类。简单地说就是一个爹可以有多个孩子,但是一个孩子只能有一个爹(隔壁老王的微笑)

    从上可以看到,父类存放共性,子类存放特性,所以它的作用是

    1.解决了代码重复问题,提高代码的维护性和复用性。

    2.更多的是表现出一个体系。

     在Java中,除了object类,每一个类都有一个直接父类,object类是java语言的根类,也就是说object是老祖宗。

     二、方法重写/覆盖

    1.当在程序中通过对象调用方法时,会先在子类中查找有没有对应的方法,若子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法。

     当调用自子类中的方法时,如果子类中没有这个方法,可以直接访问父类中的同名方法。

    子类中出现与父类一模一样的方法时,会出现覆盖操作,也称为override重写、复写或者覆盖。

     

    当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容。

     2.方法覆盖的原则

    ① 子类方法覆盖父类方法,必须要保证权限大于等于父类权限。

     private修饰的方法不能被子类所继承,也就不存在覆盖的概念

    当父类方法大于访问权限大于子类,编译报错

    写法上必须一模一样:方法的返回值类型 方法名 参数列表都要一样。

     注意:

      1)只有方法有覆盖的概念,字段没有,方法覆盖解决了,父类的某一个行为不符合子类的特征,例如,鱼是鲸鱼的父类,鱼的呼吸行为是用鳃呼吸,而鲸鱼不是

      2)对于父类的包访问权限成员变量,如果子类和父类在同一个包下,则子类能够继承;否则,子类不能够继承;

      3)对于子类可以继承的父类成员变量,如果在子类中出现了同名称的成员变量,则会发生隐藏现象,即子类的成员变量会屏蔽掉父类的同名成员变量。如果要在子类中访问父类中同名成员变量,需要使用super关键字来进行引用。

      4)对于父类的包访问权限成员方法,如果子类和父类在同一个包下,则子类能够继承;否则,子类不能够继承;

      5)对于子类可以继承的父类成员方法,如果在子类中出现了同名称的成员方法,则称为覆盖,即子类的成员方法会覆盖掉父类的同名成员方法。如果要在子类中访问父类中同名成员方法,需要使用super关键字来进行引用。

    三、super关键字

    1.重写后我们怎么去调用父类中的方法呢?

    当我们重写后,用子类的某一方法去调用父类被重写后的方法时效果如下

    这里其实在子类中skill()方法中默认的是 this.atack();

     那我们怎么办呢?

    用super关键字就可以访问父类中被重写的方法

     四、子类初始化过程

    即创建子类对象的过程

    在创建子类对象之前会先创建父类对象,调用子类构造器之前,在子类构造器中会先调用父类的构造器,默认无参。

    如果父类不存在可以被子类访问的构造器,则不能存在子类,也就是全是私有的,则不能有子类。

    public static void main(String[] args) {
    //创建子类对象
        TianHuiHero th=new TianHuiHero();
    }
    class DotaHero {
        String name;
        int    age;
        String race;
        String belive;
    //父类的无参构造,打印文字方便观察
        public DotaHero() {
            System.out.println("倒不了的塔");
        }
    }
    class TianHuiHero extends DotaHero {
    //子类的无参构造
        public TianHuiHero() {
    //这里隐藏一个 super();
            System.out.println("天辉胜利");
        }
        
    }

    执行打印,先调用了父类的构造函数,其实父类构造函数也有一个默认super()。

    如果父类没有提供无参数的构造器,此时子类必须显示通过super语句,去调用父类带有参数的构造器。

     

    父类无无参构造,而子类调用的是无参构造时,此时编译器报错。而通过显示super()语句来调用父类有参构造时程序可以编译执行。

     

    public class JiCheng {
    public static void main(String[] args) {
        TianHuiHero th=new TianHuiHero("剑圣",45,"黄色");
    }
    }
    class DotaHero {
        //当父类中的成员变量设为私有,创建子类时无法直接访问,所以需要调用父类的有参构造器间接访问。
        private String name;
        private int    age;
        String race;
        String belive;
        public DotaHero(String name,int age) {
            this.name=name;
            this.age=age;
        }
    }
    class TianHuiHero extends DotaHero {
        String color;
        public TianHuiHero(String name,int age,String color) {
    //调用父类构造,super必须作为第一句话
            super(name,age);
            this.color=color;
        }
    }
  • 相关阅读:
    聊聊CMDB的前世今生
    我是如何走上运维岗位的?谈谈新人入职运维发展的注意事项
    如何从生命周期的视角看待应用运维体系建设?
    标准化体系建设(下):如何建立基础架构标准化及服务化体系?
    标准化体系建设(上):如何建立应用标准化体系和模型?
    微服务架构时代,运维体系建设为什么要以“应用”为核心?
    Kubernetes容器化工具Kind实践部署Kubernetes v1.18.x 版本, 发布WordPress和MySQL
    Etcd常用运维命令
    Logstash生产环境实践手册(含grok规则示例和ELKF应用场景)
    Netflix业务运维分析和总结
  • 原文地址:https://www.cnblogs.com/LuckyGJX/p/8908969.html
Copyright © 2011-2022 走看看