Lazy loaded image
面向对象下
字数 11426阅读时长 29 分钟
2025-3-26
2025-3-26
type
status
date
slug
summary
tags
category
icon
password

继承

什么是继承

  • 父类怎么形成的
    • 我们的定义了多个类,发现这些类中有很多重复性的代码,我们就定义了一个父类将相同的代码抽取出来放到父类中,其他的类直接继承这个父类就可以直接使用父类中的内容了
  • 怎么去继承
    • 子类 extends 父类
  • 注意
    • 子类可以继承父类中私有和非私有成员,但是不能使用父类中私有成员
    • 构造方法不能继承
  • 继承怎么学
    • 继承不要从是否"拥有"方面来学习,要成是否能"使用"方面来学习

继承基本使用

  • 定义一个父类,其中定义重复性代码
  • 定义一个子类继承父类
    • 子类 extends 父类
  • 创建子类对象,直接使用父类中非私有成员

继承中成员访问特点

子类和父类中成员变量不重名

子类和父类中的成员变量重名

:walking:总结:看等号左边是谁,先调用谁中的成员,子类没有,找父类

子类和父类中成员方法不重名

子类和父类中成员方法重名

:walking:总结:看new的是谁,先调用谁中的方法子类没有,找父类

方法重写

介绍

  • 概述
    • 子类中有一个和父类方法名以及参数列表相同的方法
  • 前提
    • 继承
  • 访问
    • 看new的是谁,先调用谁中的方法,子类没有,找父类
  • 检测是否为重写方法
    • 写一个注解@Override
      • 若报错,则不是重写方法
      • 若不报错,则是重写方法

注意事项

  • 子类重写父类方法之后,权限必须要保证大于等于父类权限(权限指的是访问权限)
    • public->protected->默认
  • 子类方法重写父类方法,方法名和参数列表一样
  • 私有方法不能被重写,构造方法不能被重写,静态方法不能被重写
  • 子类重写父类方法之后,返回值类型应该是父类方法返回值类型的子类类型

使用场景

功能升级改造,子类需要对父类中已经实现好的功能进行重新改造
notion image

继承特点

只支持单继承,不能多继承 public class A extends B,C{} -> 错误继承支持多层维承 public class A extends B{}public class B extends c{}一个父类可以有多个子类 public class A extends c{}public class B extends c{}构造方法不能继承,也不能重写私有方法可以继承,但是不能被重写静态方法可以继承,但是不能被重写

super和this

继承中构造方法特点

:warning:new子类对象时,会初始化父类(先走父类无参构造方法)
:a:原因
  • 每个构造方法的第一行,默认都会有一个super(),不写jvm自动提供一个super()代表的是父类无参构造

super和this具体使用

super的具体使用

概述:代表的是父类引用作用:可以调用父类中的成员使用: 调用父类构造方法->在子类中的构造中写 super()->调用父类无参构造super(实参)->调用父类有参构选调用父类成员变量 super,成员变量名调用父类成员方法 super.成员方法名(实参)

this具体使用

概述 代表当前对象(哪个对象调用的this所在的方法,this就代表哪个对象)作用 区别重名的成员变量和局部变量调用当前对象中的成员使用 调用当前对象的构造:在构造中写 this():调用当前对象的无参构选this(实参):调用当前对象的有参构造调用当前对象的成员变量 this,成员变量名调用当前对象的成员方法 this.成员方法名(实参)注意 不管是super还是this,只要在构造中使用,都必须在第一行,所以二者不能同时手写出来

练习:为父类中private属性赋值

利用set赋值

利用构造方法赋值

notion image

抽象

概述

抽象类怎么来的 抽取共性方法放到父类中,发现方法没办法确定具体实现,因为每个子类对此方法的实现细节不一样,此时方法体说不清,道不明,可以定义成抽象方法抽象方法所在的类一定是抽象类关键字abstract定义抽象方法 修饰符abstract返回值类型方法名(参数):抽象类: public abstract class类名0注意: 抽象方法所在的类一定是抽象类抽象类中不一定非得有抽象方法子类继承抽象父类时,需要重写父类中所有的抽象方法不然编译报错抽象类不能new对象,只能通过new子类对象调用重写方法可以将抽象类看成是一类事物的标准,要求只要是属于这一类的,都必须要拥有抽象类中的方法,必须要给我实现,怎么证明拥有了,怎么证明实现了呢?->重写 至于这个方法怎么实现,就看子类重写之后怎么写方法体了
notion image

注意事项

抽象类不能直接new对象,只能创建非抽象子类的对象抽象类中不一定非得有抽象方法,但是抽象方法所在的类一定抽象类抽象类的子类,必须重写父类中的所有抽象方法,否则,编译报错,除非该子类也是抽象类抽象类中可以有成员变量,构造,成员方法抽象类中可以有构造方法,是供子类创建对象时,初始化父类属性使用的

综合案例

notion image

接口

接口介绍及使用

接口介绍

是一个引用类型,是一种标准规则关键字 interface 接口 public interface 接口名{}implements 实现 实现类 implement 接口名{}接口中可以定义的成员 jdk7以及之前 抽象方法 public abstract -> 即使不写 public abstract 默认也有成员变量 public static final 数据类型 变量名=值 -> 即使不写public static final ,默认也有final是最终的,被final修饰变量不能二次赋值,所以我们一般将final修饰变量视为常量jdk8默认方法 public default 返回值类型 方法名(形参){}静态方法 public static 返回值类型 方法名(形参){}jdk9私有方法 private方法

接口使用

定义接口 public interface 接口名{}实现 public class 实现类类名 implements 接口名{}使用 实现类实现接口重写接口中抽象方法创建实现类对象(接口不能直接new对象)调用重写方法

接口中成员

抽象方法(jdk7)

定义格式 public abstract 返回值类型 方法名(形参);注意 不写public abstract 默认也有的使用 定义实现类,实现接口重写抽象方法创建实现类对象,调用重写方法

默认方法(jdk8)

格式 public default 返回值类型 方法名(形参){}使用 定义实现类,实现接口默认方法可重写,可不重写创建实现类对象,调用默认方法

静态方法(jdk8)

定义格式 public static 返回值类型 方法名(形参){}使用 接口名直接调用
:warning:默认方法和静态方法可以作为临时加的小功能使用

接口中成员变量

格式 public static final 数据类型 变量名=值相关知识点 final代表最终,被它修饰的变量不能二次赋值,可以视为常量特点 不写public static final 默认也有使用 接口名直接调用注意 被static final 修饰的成员变量需要手动赋值习惯上我们会将static final 修饰成员变量名大写

接口特点

接口可以多继承 一个接口可以继承多个接口public interface InterfaceA extends InterfaceB,InterfaceC{}接口可以多实现 一个实现类可以实现一个或多个接口public class InterfaceImpl implements InterfaceA,InterfaceB{}一个子类可以继承一个父类同时实现一个或多个接口 public class zi extends Fu implements InterfaceA,InterfaceB{}注意 继承也好,实现接口也罢,只要是父类中或者接口的抽象方法,子类或者实现类都要重写
当一个类实现多给接口时,如果接口中抽象方法有重名且参数一样的,只需要重写一次
当一个类实现多个接口时,如果多个接口中默认方法有重名的,且参数一样的,必须重写一次默认方法

接口和抽象类区别

相同点 都位于继承系统中的顶端,用于被其他类实现或者继承都不能new都包含抽象方法,其子类或者实现类都必须重写这些抽象方法不同点 抽象类一般作为父类使用,可以有成员变量,构造,成员方法,抽象方法等接口成员比较单一,一般抽取接口,抽取接口都是方法,视为功能的大集合抽象类不能多继承,但是接口可以
notion image

多态

面向对象三大特征:封装、继承、多态怎么学 不要从字面意思上理解多态两个字,要从形式上掌握要知道多态好处要知道多态前提

多态的介绍

前提 必须有子父类继承或者接口实现关系必须有方法重写(没有重写,多态没有意义),多态主要玩的是方法重写new对象:父类引用指向子类对象 Fu fu=new Zi()理解为大类型接收小类型数据数据比如 double b=10注意 多态下不能直接调用子类特有功能

多态的基本使用

多态下成员访问特点

成员变量 看等号左边成员是谁 就是调谁成员变量成员方法 看new的是谁 就是调用谁的成员方法,子类没有就找父类

多态的好处

问题描述 如果使用原始new对象(等号两边一样)既能调用重写的,还能调用继承,还能调用自己特有的成员,但是多态方式new对象 只能调用重写,不能直接调用子类特有成员,那为啥还有使用多态呢?多态方式和原始方式new对象优缺点 原始方式 优点 既能调用重写的,还有调用父类非私有的还能调用自己特有的缺点 扩展性差动态方式 优点 扩展性强缺点 不能调用子类特有功能

多态中的转型

向上转型

父类引用子类对象(隐式转换) 例如:double b=1

向下转型

概述 好比强转,将大类型转小类型表现形式 父类类型 对象名1 = new 子类对象 向上转型 -> double b=1子类类型 对象名2 = (子类类型) 对象1 向下转型 -> int i =(int) b想要调用子类特有功能,我们需要向下转型

转型中可能出现的问题

如果等号左右两边类型不一致,公出现类型转换异常(ClassCastException)解决 在向下转型之前,先判断类型怎么判断类型 instanceof判断结果时boolean型使用 对象名 instanceof 类型 变量名 -> 判断的是关键字前面对象是否符合关键字后面类型

多态综合练习

定义笔记本类,具备开机,关机和使用USB设备的功能。 具体是什么USB设备,笔记本并不关心,只要符合USB规格的设备都可以。 鼠标和键盘要想能在电质上使用,那么鼠标和键盘也必须遵守USB规范,不然鼠标和键盘的生产出来无法使用; 进行描述笔记本类,实现笔记本使用USB鼠标、USB键盘
  • USB接口,包含开启功能、关闭功能
  • 笔记本类,包含运行功能、关机功能、使用USB设备功能
  • 佩标类,要符合USB接口
  • 键盘类,要符合USB接口
分析

权限修饰符

概述

在Java中提供了四种访问权限,使用不同的访问权限修饰符修饰时,被修饰的内容会有不同的访问权限,
  • public
    • 公共的,最高权限,被public修饰的成员,在哪里都能访问
  • protected
    • 受保护的
  • default:
    • 默认的注意不写权限修饰符就是默认权限,不能直接把default写出来
  • private
    • 私有的,只能在自己的类中直接访问

不同权限访问能力

public
protected
default
private
同类
yes
yes
yes
yes
同包不同类
yes
yes
yes
no
不同包子父类
yes
yes
no
no
不同包非子类
yes
no
no
no
public 具有最大权限,private有最小权限
编写代码时,如果没有特殊的考虑,建议这样使用权限
  • 属性用private 封装思想
  • 成员方法public 便于调用
  • 构造public 便于new对象

final关键字

概述 最终的使用 修饰一个类修饰一个方法修饰一个局部变量修饰一个成员变量修饰一个对象怎么学final 只需要知道被final修饰之后特点是啥

final修饰类

格式 public final class 类名 {}特点 被final修饰类不能被继承

final修饰方法

格式 修饰符final 返回值类型 方法名(形参){}特点 被final 修饰的方法,不能被重写注意 final和abstract不能同时修饰一个方法

final修饰局部变量

格式 final 数据类型 变量名=值特点 被final修饰变量不能二次赋值

final修饰对象

格式 final 数据类型 对象名 = new 对象名()特点 被final修饰对象 地址值不能被改变,但是对象中属性值可以改变

final修饰成员变量

格式 final 数据类型 变量名=值特点 需要手动赋值不能二次赋值

代码块

构造代码块

格式{​ 代码}执行特点优先于构造方法执行每new一次,都会执行一次构造代码块

静态代码块

格式static {​ 代码}执行特点静态代码块优先构造代码块和构造方法只执行一次

静态代码块使用场景

如果想让一些数据最先初始化,而且只需要初始化一次,就可以将这些数据放到静态代码块中
notion image

内部类

什么时候需要内部类当一个事物的内部,还有一个部分需要完整的结构去描述,而这个内部完整结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类比如:人类都有心脏,人类本身需要用属性,行为去描述,那么人类内部的心脏也需要心脏特殊的属性和行为去描述,此时心脏就可以定义成内部类,人类中的一个心脏类在java中允许一个类定义于另外一个类内部,前者就被称为内部类,后者称为外部类class A{ class B { }}分类成员内部类(静态和非静态)局部内部类匿名内部类(重点)

成员内部类

静态成员内部类

格式直接定义内部类的时候加上static 关键字public class A{ static class B{ }}注意内部类可以定义属性,方法,构造静态内部类可以被final或者abstract修饰,被final修饰不能被继承,被abstract修饰不能用new静态内部类不能调用外部的非静态成员内部类还可以被四种权限修饰符修饰调用静态内部类成员外部类.内部类 对象名=new 外部类.内部类()

非静态成员内部类

格式直接定义内部类的时候加上static 关键字public class A{ class B{ }}注意内部类可以定义属性,方法,构造静态内部类可以被final或者abstract修饰,被final修饰不能被继承,被abstract修饰不能用new静态内部类不能调用外部的非静态成员内部类还可以被四种权限修饰符修饰调用静态内部类成员外部类.内部类 对象名=new 外部类.new 内部类()

外部类和内部类重名变量区分

局部内部类

局部内部类基本操作

可以定义方法中,代码块中,构造方法中调用类

局部内部实际操作

接口类型作为方法参数传递和返回
抽象类作为方法参数传递和返回值
抽象类作为方法参数传递,传递参数时传递是其子类对象抽象类作为方法返回值类型返回时,实际返回其子类对象
普通类做方法参数和返回值
普通类作为方法参数传递,传递对象普通类作为方法返回值返回,返回的是对象
局部内部类实际操作

匿名内部类

所谓匿名内部类可以理解为没有显式声明类名的内部类
  • 问题描述
    • 我们如果想实现接口,简单使用一次抽象方法,我们就需要创建一个实现类,实现这个接口,重写抽象方法,还要new实现类对象,所以我们在想知果就单纯的想使用一次接口中的方法,我们能不能不这么麻烦呢?可以
    • 创建实现类,实现接口
    • 重写方法
    • 创建实现类对象
    • 调用方法
  • 如果单独使用一下接口中方法,我们就没必要经过以上四步,我们就可以四合一
  • 匿名内部类怎么学
    • 就按照一种格式来学,这一种格式就代表实现类对象或者子类对象
  • 格式
    notion image
    什么时候用匿名内部类 当简单调用一次接口中的方法,我们就可以使用匿名内部类将一种格式代表实现类对象或者子类对象来看待来学习匿名内部类会编译生成咱们不用管我们只需要利用之前学习格式去new对象,调用重写方法即可

    匿名内部类复杂用法参数传递

    notion image

    匿名内部类复杂用法返回值返回

    notion image
    上一篇
    异常处理
    下一篇
    面向对象上