暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

什么是继承?

理想二旬不止 2021-09-14
351

为满足移动端和PC端的双重阅读体验,以及文章质量的保证,开始重构的以及新写的文章都会基于 “语雀” 平台编写,公众号会同步刚发布的文章,但随后的修改或者更新只会在语雀中维护。

👉 点击底部左下角 “阅读原文” 即可跳转到文章最新页面!
理想二旬不止@BWH_Steven


1. 继承的基本认识

1.1 概述

1.1.1 什么是继承


先不谈定义,看上图中,动物可以根据饮食习惯分成食草动物食肉动物,即由动物派生出了两种类型,这几种动物其实还是一个抽象的概念,还是那句话,当我们提到动物、食草动物、食肉动物,我们仍然没法确定具体是什么动物,所以它们还是一个类的概念,即继承也是一个类层面的概念。同时例如食草动物本身就是动物的一种,所以动物的所有特质它也是具有的,同时它又会有一些自己独特的属性或者行为。(父类更通用,子类更具体)


1.1.2 定义

定义:继承就是在一个已有类的基础上派生出新类。
子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
功能:有了继承以后,我们定义一个类的时候,可以在一个已经存在的类的基础上,还可以定义自己的新成员。
格式:

class 子类名 extends 父类名 {}

复制

1.2 优点

  1. 提高了代码的复用性(因为子类是基于父类派生出来的,继承了父类的特征和行为)

  2. 提高了代码的维护性(通过少量的修改,满足不断变化的具体要求)

  3. 让类与类产生了一个关系,是多态的前提(后面会专篇讲解多态)

1.3 缺点

  1. 让类的耦合性增强,这样某个类的改变就会影响其他和该类相关的类

  • 原则:低耦合,高内聚。

  • 耦合:类与类的关系

  • 内聚:自己完成某件事情的能力

  1. 打破了封装性

1.4 特点

  1. Java只支持单继承,不支持多继承(C++支持)

  2. Java支持多层继承(继承体系)

  • 儿子继承爸爸 爸爸继承爷爷 儿子可以通过爸爸继承爷爷

1.5 注意

  1. 子类只能继承父类所有非私有成员(成员方法和成员变量)

  2. 子类不能继承父类的构造方法,但是可以通过super关键字去访问方法

  3. 不要为了部分功能而继承(多层继承会使得子类继承多余的方法)

  4. 子类的方法访问变量的查找顺序:

  • 在子类方法的局部范围找,有就使用

  • 在子类的成员范围找,有就使用

  • 在父类的成员范围找,有就使用

  • 找不到,就报错。

2. super 关键字

观察下面的代码,Son 类继承于 Father 类,两者都有一个 int 类型的变量 num,在主函数中,实例化 Son 类,构建出一个 son 对象,调用 show 方法,观察三行语句的输出

public class ExtendsDemo {
    public static void main(String[] args) {
        Son son = new Son();
        son.show();
    }
}

class Father {
    public int num = 10;
}

class Son extends Father {
    public int num = 20;

    public void show() {
        int num = 30;
        System.out.println(num);
        System.out.println(this.num);
        System.out.println(super.num);
    }
}

复制

输出结果如下:

30
20
10

复制

分析结果:

  • 输出 num,打印出来的是 30 即, show 方法中遵循着就近原则

  • 输出 this.num,打印出来的是 20,因为 this 代表本类对应的引用,即这个子类的成员属性 num = 20

  • 输出 super.num,打印出来的是 10,因为 super 代表父亲存储空间的标识(可以理解为父亲引用)可以操作父亲的成员属性 num = 10

触类旁通,不仅成员属性的调用是这样,构造函数、成员方法也是这样:

  1. 调用成员变量

  • this.成员变量 调用本类的成员变量

  • super.成员变量 调用父类的成员变量

  1. 调用构造方法

  • this(…) 调用本类的成员变量

  • Super(…)调用父类的成员变量

  1. 调用成员方法

  • this.成员方法 调用本类的成员方法

  • super.成员方法 调用父类的成员方法

3. 继承中的关系

3.1 继承中构造方法的关系

关系:子类中所有的构造方法默认都会访问父类中空参数的构造方法
理由:因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化.
注意:子类每一个构造方法的第一条语句默认都是:super() ,如果父类没有无参构造方法,那么子类的构造方法会报错,所以子类中一定要有一个去访问父类的构造方法,否则父类数据就没有初始化。
解决方法:

  • 在父类中加一个无参构造方法

  • 通过使用super关键字去显示的调用父类的带参构造方法

  • 子类通过this去调用本类的其他构造方法

注意事项;

  • this(…) 或者 super(…) 必须出现在第一条语句上。

  • 否则就可能对父类的数据进行了多次初始化

3.2 继承中成员方法的关系

子类中的方法和父类中的方法声明一样
通过子类调用方法:

  • 先找子类中,看有没有这个方法,有就使用

  • 再看父类中,看有没有这个方法,有就是用

  • 如果没有就报错(不去看父亲的父亲)

4. 方法重写(override)

方法重写:子类中出现了和父类中方法声明一模一样的方法,它要区别于方法重载,方法重载仅仅是方法名一样
子类重写的应用:当子类需要父类的功能,而功能主体子类又有自己特有的内容时,这样既沿袭了父类的功能,又定义了子类特有的功能。

super.方法名(参数名); //避免重复代码

复制

5. final关键字

final 关键字声明类可以把类定义为不能继承的,即最终类,或者用于修饰方法,该方法不能被子类重写:
Final 修饰变量的初始化时机

  • 被final修饰的变量只能赋值一次

  • 在构造方法完毕前(非静态的常量)

// 声明方法
final class 类名{
    //类体
}

// 声明类
修饰符(public/private/default/protectedfinal 返回值类型 方法名(){
    //方法体
}

复制

🔥️ 语雀地址:

  • https://www.yuque.com/ideal-20

🔥️ 本篇语雀地址:

  • https://www.yuque.com/ideal-20/java/kar8c8

🔥️ 或者点击左下角 “阅读原文”

文章转载自理想二旬不止,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论