Java面向对象的继承

继承

  • 继承是面向对象的三大特性之一

  • 继承基本作用:代码复用;重要作用:有了继承才能有以后的“方法的覆盖”和“多态”

  • 继承语法格式:

      [修饰符列表] class 类名 extends 父类名{
    类体
    }
  • Java语言当中的继承只支持单继承

  • 术语:

    B类继承A类,其中:

    • A类称为:父类、基类、超类、superclass
    • B类称为:子类、派生类、subclass
  • Java语言中子类继承父类:

    • 私有的不支持
    • 构造方法不支持
    • 其他数据都可以被继承
  • Java语言中假设没有显示的继承任何类,默认继承JavaSE库提供的java.lang.Object类

public class ExtendsTest01 {

    public static void main(String[] args) {

        C c1 = new C();

        c1.doSome();    // 这里调用的doSome方法是从B类中继承的
}
} class A{
public void doSome() {
System.out.println("do some !");
}
} class B extends A{ } class C extends B{ }

方法的覆盖

【回顾】Java中的·方法重载:

  • 方法重载称为Overload

  • 什么时候能用

    在同一个类当中,方法完成功能相似,建议方法同名

  • 什么样条件构成方法重载

    • 在同一个类当中
    • 方法名相同
    • 参数列表不同:类型、顺序、个数
  • 方法重载与什么无关

    • 方法的返回值类型无关
    • 方法的修饰符列表无关

【正片】方法覆盖

  • 方法覆盖【override官方】又被称作方法重写【overwrite】

  • 什么时候使用方法覆盖

    当父类中的方法已经无法满足当前子类的需求,子类有必要将父类中继承的方法进行重新编写,这个过程称为方法重写/方法覆盖

  • 代码满足什么条件会触发方法覆盖?

    • 发生在具有继承关系的父子类之间
    • 返回值类型相同,方法名相同,形参数列表相同
    • 访问权限不能更低,可以更高
    • 抛出异常不能更多,可以更少
  • 方法重新建议复制过去改【防止写错】

  • 注意:

    • 私有方法不能继承,所以不能覆盖
    • 构造方法不能继承,所以不能覆盖
    • 静态方法不存在覆盖【后面多态详讲】
    • 覆盖只针对方法,不谈属性
// 创建动物类
public class Animal { public void move() {
System.out.println("动物在移动");
}
}
// 创建猫类
public class Cat extends Animal{ // 重新父类方法
public void move() {
System.out.println("猫在走猫步");
}
}
// 创建鸟类
public class Bird extends Animal{ // 重新父类方法
public void move() {
System.out.println("鸟在飞");
}
}
public class OverrideTest01 {

    public static void main(String[] args) {

        // 创建动物对象
Animal a = new Animal();
a.move(); // 创建猫对象
Cat c = new Cat();
c.move(); // 创建鸟对象
Bird b = new Bird();
b.move();
}
}

多态

Java中多态机制【基础规则】

多态作用:

降低程序的耦合度【解耦合】,提高程序的可拓展性【尽量使用】

  • 面向对象三大特征:封装、继承、多态

  • 关于多态中涉及的概念:

    • 向上转型(upcasting)

      • 子类型 --> 父类型

        又被称为:自动类型转换

      • 通过运行一定不会出问题

    • 向下转型(downcasting)

      • 父类型 --> 子类型

        又被称为:强制类型转换【需要加强制类型转换符】

      • 通过运行可能出问题【著名异常:java.lang.ClassCastException】

    • 无论是向下转型(upcasting)还是向上转型(downcasting),两种类型之间必须要有继承关系。没有继承关系无法通过编译

    • 当调用的方法是子类型特有,在父类型当中没有。必须进行向下转型(downcasting)

    • 在向下转型(downcasting)中如何避免 ClassCastException 异常

      使用 instanceof 运算符

        (引用 instanceof 数据类型名)

      计算结果为 Boolean【布尔类型】

      • true:表示这个引用指向的对象是此数据类型
      • false:表示这个引用指向的对象不是此数据类型
    • Java规范中要求:在使用强制类型转换前,建议采用 instanceof 运算符判断,避免 ClassCastException 异常

Animal、Cat、Bird三个类之间的关系:

  • Cat 继承 Animal
  • Bird 继承 Animal
  • Cat 与 Bird无继承关系
// 创建动物类
public class Animal { public void move() {
System.out.println("动物在移动");
}
}
// 创建猫类
public class Cat extends Animal{ // 重新父类方法
public void move() {
System.out.println("猫在走猫步");
} // 不是从父类中继承的方法
// 这个方法是子类对象特有行为
public void catchMouse() {
System.out.println("猫抓老鼠");
}
}
// 创建鸟类
public class Bird extends Animal{ // 重新父类方法
public void move() {
System.out.println("鸟在飞");
} // 子类对象特有行为
public void fly() {
System.out.println("Bird fly !");
}
}
public class Test {

    public static void main(String[] args) {

        // 以前编写的程序

        // 创建动物对象
Animal a1 = new Animal();
a1.move(); // 创建猫对象
Cat c1 = new Cat();
c1.move();
c1.catchMouse(); // 创建鸟对象
Bird b1 = new Bird();
b1.move(); // 使用动态机制
System.out.println("-----以下使用动态机制----"); Animal a2 = new Cat(); // 想象 long num = 10;
// Cat is a Animal
// new Cat()创建的对象类型是Cat,Animal a2中 a2 引用的数据类型是Animal,可见它们进行类型转换
// 子类型转换父类型,称为向上转型(upcasting),或者自动类型转换 // Bird b2 = new Cat(); Bird与Cat无继承关系 // 编译器只会把a2类型视作Animal
// 运行时是看底层的实际内容
a2.move(); // 猫在走猫步 // a2.catchMouse(); 报错
// 编译器检查为Animal类型,Animal中没有catchMouse()方法,导致静态绑定失败 // 需求:需要a2去执行catchMouse()方法
// 可以通过向下转型(downcasting),强制转换,同样需要两者有继承关系
Cat c2 = (Cat)a2;
c2.catchMouse(); // 父类型引用指向子类型对象【多态】
// 以下程序编译无错语法允许,但运行阶段报错JVM堆内存实际存在的是Bird对象
// 类型之间不存在如何继承关系,会发生著名异常:java.lang.ClassCastException
// 触发一般在向下转型(downcasting),一定注意 // Animal a3 = new Bird();
// Cat c3 = (Cat)a3; // c3.catchMouse(); 报错 著名异常:java.lang.ClassCastException // 避免ClassCastException
Animal a3 = new Bird(); if(a3 instanceof Cat) {
Cat c3 = (Cat)a3;
c3.catchMouse();
}else if(a3 instanceof Bird){
Bird b3 = (Bird)a3;
b3.fly();
} }
}
  1. java程序永远都分为编译阶段和运行阶段
  2. 先分析编译阶段,再分析运行阶段,编译无法通过,根本无法运行
  3. 编译阶段编译器检查a2这个引用的数据类型是Animal,由于Animal.class字节码当中有move()方法,所以编译通过,这个过程我们称为静态绑定,编译阶段绑定。只有静态绑定成功之后才有程序运行
  4. 在程序运行阶段,JVM堆内存中真实创建的对象是Cat对象,那么上述程序中 a2.move(); 一定调用Cat对象的move()方法【方法重写无关】,称为动态绑定,运行阶段绑定
  5. 无论重写与否,运行阶段只与底层实际关联

父类型引用指向子类型对象这种机制导致程序在编译阶段绑定和运行阶段绑定两种不同的形态,这种机制可以成为一种动态语法机制


Java面向对象



学习笔记--Java面向对象的继承的更多相关文章

  1. 我的Java学习笔记-Java面向对象

    今天来学习Java的面向对象特性,由于与C#的面向对象类似,不需详细学习 一.Java继承 继承可以使用 extends 和 implements 这两个关键字来实现继承. extends:类的继承是 ...

  2. C++ Primer 学习笔记_69_面向对象编程 --继承情况下的类作用域

    面向对象编程 --继承情况下的类作用域 引言: 在继承情况下,派生类的作用域嵌套在基类作用域中:假设不能在派生类作用域中确定名字,就在外围基类作用域中查找该名字的定义. 正是这样的类作用域的层次嵌套使 ...

  3. 学习笔记-Java面向对象

    学习来源: B站[狂神说Java]Java零基础学习视频通俗易懂 static关键字详解 package com.oop.demo07; //static public class Student{ ...

  4. Java学习笔记之---面向对象

    Java学习笔记之---面向对象 (一)封装 (1)封装的优点 良好的封装能够减少耦合. 类内部的结构可以自由修改. 可以对成员变量进行更精确的控制. 隐藏信息,实现细节. (2)实现封装的步骤 1. ...

  5. [java学习笔记]java语言核心----面向对象之this关键字

    一.this关键字 体现:当成员变量和函数的局部变量重名时,可以使用this关键字来区别:在构造函数中调用其它构造函数 原理:         代表的是当前对象.         this就是所在函数 ...

  6. 《Java核心技术·卷Ⅰ:基础知识(原版10》学习笔记 第5章 继承

    <Java核心技术·卷Ⅰ:基础知识(原版10>学习笔记 第5章 继承 目录 <Java核心技术·卷Ⅰ:基础知识(原版10>学习笔记 第5章 继承 5.1 类.超类和子类 5.1 ...

  7. [java学习笔记]java语言核心----面向对象之构造函数

    1.构造函数概念 特点: 函数名与类名相同 不用定义返回值类型 没有具体的返回值 作用:                给对象进行初始化 注意: 默认构造函数 多个构造函数是以重载出现的 一个类中如果 ...

  8. Lua学习笔记:面向对象

    Lua学习笔记:面向对象 https://blog.csdn.net/liutianshx2012/article/details/41921077 Lua 中只存在表(Table)这么唯一一种数据结 ...

  9. ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则

    ASP.NET MVC 学习笔记-7.自定义配置信息   ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...

  10. UML和模式应用学习笔记-1(面向对象分析和设计)

    UML和模式应用学习笔记-1(面向对象分析和设计) 而只是对情节的记录:此处的用例场景为:游戏者请求掷骰子.系统展示结果:如果骰子的总点数是7,则游戏者赢得游戏,否则为输 (2)定义领域模型:在领域模 ...

随机推荐

  1. Vue——生命周期

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. Kubernetes操作图

  3. zabbix第一天 zabbix安装,添加监控项

    1. zabbix 介绍 公司规模大,服务器众多,运维人员需要用到zabbix来监控整个服务器的运行状况,避免服务器故障后运维人员无法察觉. 清华zabbix源: https://mirrors.tu ...

  4. TensorRT环境配置(VS+opencv4.5)

    1 TensorRT下载 下载与TensorRT相匹配的CUDA和cuDNN版本:https://docs.nvidia.com/deeplearning/tensorrt/archives/tens ...

  5. ajax 请求接口实例

    通过 HTTP 请求加载远程数据. jQuery 底层 AJAX 实现.简单易用的高层实现见 $.get, $.post 等.$.ajax() 返回其创建的 XMLHttpRequest 对象.大多数 ...

  6. mvn 打包报错:no compiler is provided in this environment

    最近公司换了电脑,系统也从 win7 升级到 win11,开发环境都重新安装了一遍,然后在 idea 用mvn 执行打包命令 mvn clean package 报错: no compiler is ...

  7. LeetCode 680. Valid Palindrome II 验证回文字符串 Ⅱ(C++/Java)

    题目: Given a non-empty string s, you may delete at most one character. Judge whether you can make it ...

  8. .NET借助虚拟网卡实现一个简单异地组网工具

    由于工作需要,经常需要远程客户的服务器,但是并不是所有服务器都能开外网端口,使用向日葵等软件终究还是不太方便,于是找了很多工具,包括zerotier 等,但是由于服务器在国外等有时候还不同, 于是开始 ...

  9. 服务器安装mysql

    数据库连接操作 修改root的hostupdate user set host='%' where user='root' and host ="127.0.0.1"flush p ...

  10. 在ftl模板中调整表格