Saul's blog Saul's blog
首页
后端
分布式
前端
更多
分类
标签
归档
友情链接
关于
GitHub (opens new window)

Saul.J.Wu

立身之本,不在高低。
首页
后端
分布式
前端
更多
分类
标签
归档
友情链接
关于
GitHub (opens new window)
  • Java入门基础

    • 计算机常识

    • Java语言概述

    • 基本语法

    • 数组

    • 面向对象

      • 面向对象
      • 类和对象
      • 类的成员-属性
      • 类的成员-方法
      • 类的成员-构造器
      • 面向对象特性-封装
      • this关键字
      • package关键字
      • import关键字
      • 面向对象特征-继承
        • 前言
        • 什么是继承?
        • 为什么要有继承?
        • 如何使用继承?
        • "是一个"与"像是一个"的关系
        • 什么时候该使用继承?
        • 单继承与多层继承举例
        • 单继承结构
      • 方法的重写
      • 访问权限修饰符
      • super关键字
      • 子类对象实例化的全过程
      • 面向对象特征-多态
      • 强制类型转换
      • Object类
      • 包装类
      • static关键字
      • 单例设计模式
      • main方法
      • 类的成员-代码块
      • final关键字
      • 抽象类与抽象方法
      • 接口
      • 类的成员-内部类
    • 异常处理

  • Java核心基础

  • 设计模式

  • Web开发

  • SpringBoot

  • 微服务

  • Elasticsearch

  • 运维

  • 后端
  • Java入门基础
  • 面向对象
SaulJWu
2020-12-11

面向对象特征-继承

# 前言

面向对象的三大特征:

  • 封装 (Encapsulation)

  • 继承 (Inheritance)

  • 多态 (Polymorphism)

接下来我们学习继承。

# 什么是继承?

使用extends关键字来继承另一个类

语法格式

class Subclass extends SuperClass{

}
1
2
3
  • Subclass:新建的类(正式名称叫作继承类或者子类)
  • extends:关键字
  • SuperClass:原始类(正式名称叫作基类、超类或父类)

# 为什么要有继承?

多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。

此处的多个类称为子类(派生类),单独的这个类称为父类(基类或超类)。可以理解为:“子类is a 父类”。

在创建了一个类之后,即使另一个新类与其具有相似的功能,你还是得重新创建一个新类。但我们若能利用现成的数据类型,对其进行“克隆”,再根据情况进行添加和修改,情况就显得理想多了。“继承”正是针对这个目标而设计的。但继承并不完全等价于克隆。在继承过程中,若原始类(正式名称叫作基类、超类或父类)发生了变化,修改过的“克隆”类(正式名称叫作继承类或者子类)也会反映出这种变化。

作用:

  • 继承的出现减少了代码冗余,提高了代码的复用性
  • 继承的出现,更有利于功能的扩展。
  • 继承的出现让类与类之间产生了关系,提供了多态的前提。

# 如何使用继承?

  • 子类继承了父类,就继承了父类的方法和属性
  • 在子类中,可以使用父类中定义的方法和属性,也可以创建新的属性和方法。
  • 使用格式:对象.属性或者对象.方法
  • 在Java 中,继承的关键字用的是“extends”,即子类不是父类的子集,而是对父类的“扩展”。
class Person{
    private int age;
    private String name;
    //省略setter和getter
}

class Student extends Person{
    //新的属性
    private int score;
    
    //新的方法
    public void Study(){
       System.out.println("学习...");
    }
    
    //省略setter和getter
}

Class Test{
    public static void main(String[] args){
      Student stu = new Student();
      stu.setAge(14);//继承了父类的属性和方法,可以直接使用。
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

注意:

  • 子类不能直接访问/调用父类中私有的(private)的成员变量和方法。虽然不能访问,但是还是可以继承父类中的所有成员变量和方法。

# "是一个"与"像是一个"的关系 (opens new window)

对于继承可能会引发争论:继承应该只覆盖基类的方法(不应该添加基类中没有的方法)吗?如果这样的话,基类和派生类就是相同的类型了,因为它们具有相同的接口。这会造成,你可以用一个派生类对象完全替代基类对象,这叫作"纯粹替代",也经常被称作"替代原则"。在某种意义上,这是一种处理继承的理想方式。我们经常把这种基类和派生类的关系称为是一个(is-a)关系,因为可以说"圆是一个形状"。判断是否继承,就看在你的类之间有无这种 is-a 关系。

有时你在派生类添加了新的接口元素,从而扩展接口。虽然新类型仍然可以替代基类,但是这种替代不完美,原因在于基类无法访问新添加的方法。这种关系称为像是一个(is-like-a)关系。新类型不但拥有旧类型的接口,而且包含其他方法,所以不能说新旧类型完全相同

# 什么时候该使用继承?

利用is-a判断, 该不该使用继承关系。

比如学生是人,那么Student 可以继承 Person。

比如dog is a Animal,那么可以使用继承关系。

比如储蓄卡是一种银行卡,那么可以使用继承关系。

比如cat is dog?那么就不应该使用继承关系。

当然,不单只考虑is-a来判断,还要根据实际业务场景来判断,具体问题具体分析,我上面说是可以继承,而不是一定要继承,要分清楚。

Java只支持单继承和多层继承,不允许多重继承

一个子类只能有一个父类。

一个父类可以派生出多个子类。

# 单继承与多层继承举例

image-20201211143536292

多层继承,后面继承的类拥有前面所有继承的属性和方法。

# 单继承结构 (opens new window)

所有的类都直接或间接继承Object类

如果没有显式声明一个类的父类的话,则此类直接继承object类

自从 C++ 引入以来,一个 OOP 问题变得尤为突出:是否所有的类都应该默认从一个基类继承呢?这个答案在 Java 中是肯定的(实际上,除 C++ 以外的几乎所有OOP语言中也是这样)。在 Java 中,这个最终基类的名字就是 Object。

Java 的单继承结构有很多好处。由于所有对象都具有一个公共接口,因此它们最终都属于同一个基类。相反的,对于 C++ 所使用的多继承的方案则是不保证所有的对象都属于同一个基类。从向后兼容的角度看,多继承的方案更符合 C 的模型,而且受限较少。

对于完全面向对象编程,我们必须要构建自己的层次结构,以提供与其他 OOP 语言同样的便利。我们经常会使用到新的类库和不兼容的接口。为了整合它们而花费大气力(有可能还要用上多继承)以获得 C++ 样的“灵活性”值得吗?如果从零开始,Java 这样的替代方案会是更好的选择。

另外,单继承的结构使得垃圾收集器的实现更为容易。这也是 Java 在 C++ 基础上的根本改进之一。

由于运行期的类型信息会存在于所有对象中,所以我们永远不会遇到判断不了对象类型的情况。这对于系统级操作尤其重要,例如异常处理 (opens new window)。同时,这也让我们的编程具有更大的灵活性。

帮我改善此页面 (opens new window)
#extends#继承
上次更新: 2020/12/18, 12:50:58
import关键字
方法的重写

← import关键字 方法的重写→

最近更新
01
zabbix学习笔记二
02-28
02
zabbix学习笔记一
02-10
03
Linux访问不了github
12-08
更多文章>
Theme by Vdoing | Copyright © 2020-2022 Saul.J.Wu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式