二,面向对象

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

1. 封装

1.1 封装的定义

  1. 封装旨在:正确设计对象的属性和方法

  2. 对象代表什么, 就得封装对应的数据, 并提供数据对应的行为, 比如, 人画圆, 画圆的方法需要定义在圆中

1.2 构造方法

1.2.1 定义

  1. 构造方法也叫构造器,构造函数

  2. 作用是在创建对象时候给成员变量初始化

image

  1. 构造方法的定义

  2. 如果没有定义构造方法, 系统将给出一个默认的无参数构造方法

  3. 如果定义了构造方法, 系统将不再提供默认的构造方法

  4. 带参构造方法和无参构造方法属于方法的重载

1.2.2 this的内存原理

image

1.2.3 局部变量和成员变量区别

image

1.3 标准的JavaBean类

  1. 下在ptg插件, 可以调用生成构造方法
    image

1.4 对象内存图(了解)

1.4.1 一个对象的内存图

image
main方法结束后释放堆内存

1.4.2 两个对象的内存图

image
image

1.4.3 两个引用指向同一个对象

image

1.5. Static

1.5.1 定义

  1. static表示静态, 是Java中的一个修饰符, 可以修饰成员方法, 成员变量

  2. 被static修饰的成员变量叫静态变量, 被static修饰的成员方法叫静态方法

  3. 特点是被该类所有对象共享, 不属于对象而属于类, 调用方式两种:

    • 类名调用(推荐)
    • 对象名调用
  4. 静态方法多用在工具类和测试类中, JavaBean类中很少使用

  5. 三大类:

    • JavaBean类: 用来描述一类事物的类, 比如Student, Dog, Cat
    • 测试类: 用来检查其他类是否书写正确, 带有main方法的类, 是程序的入口
    • 工具类(类名见名知意, 私有化构造方法, 方法定义为静态): 不是描述一类事物的, 而是帮助我们做一些事情的类

1.5.2 static内存图

  1. 静态变量是随着类的加载而加载的, 优先于对象出现的
    image

1.5.3 static注意事项

  1. 静态方法只能访问静态方法和静态变量, 非静态方法没有限制

  2. 静态方法中没有this关键字

  3. 非静态方法中含有隐藏的this关键字, 不能自己赋, 而是有虚拟机赋值的

1.5.4 重新认识main

虽然调用函数是静态的, 但也可以在静态方法中创建对象使用非静态
image

2. 继承

2.1 继承的定义

  1. Java中提供一个关键字extends, 用这个关键字, 可以让一个类和另一个类建立起继承关系, 并可以创建自己的方法
  // Student 称为子类(派生类), Person 称为父类(基类, 超类)
  public class Student extends Person {}

2.2 继承的特点

  1. Java只支持单继承(一个子类只能继承一个父类), 不支持多继承(子类不能同时继承多个父类), 但支持多层继承
    image

  2. Java中的类都直接或间接继承于Object类

2.3 子类继承的父类内容

  1. 成员变量都能继承
    image

  2. 父类的构造方法不能被子类继承

  3. 只有父类中的虚方法才能被子类继承
    image

2.4 继承的内存图

2.4.1 父类成员变量非私有

  1. 和以往不同的是, 加载字节码的文件时, 会把父类的字节码也加载下来, 创建对象时, 一部分存储本类的变量和方法, 另一部分存储父类的
    object理应载入字节码, 但是方便起见, 没有展示
    image\

2.4.2 父类变量私有

  1. 私有的父类变量也可以继承, 但是不能直接调用
    image

2.4.3 成员方法

查看是否位于虚方法表中, 若有直接调用, 若无则逐级上找, 找到fushow2是private, 报错
image

2.5 成员变量的访问特点

  1. super调用直接访问父类
    image

2.6 方法的重写

  1. 当父类的方法不能满足子类现在的需求时, 需要进行方法重写

  2. 在继承体系中, 子类出现了和父类中一模一样的方法声明, 我们就称子类这个方法是重写的方法

  3. @override重写注解
    (1) @override是放在重写后的方法上, 校验子类重写时语法是否正确
    (2) 加上注解后如果有红色波浪线, 表示语法错误
    (3) 建议重写方法都加上@override注解, 代码安全, 优雅

  4. 方法的重写本质上是覆盖虚方法表中继承的方法

2.7 构造方法的访问特点

  1. 父类中的构造方法不会被子类继承, 但是子类可以通过super调用

  2. 子类中的所有构造方法默认先访问父类中的无参构造, 再执行自己
    这是因为子类在初始化的时候, 有可能会用到父类中的数据, 如果父类没有完成初始化, 子类将无法使用父类的数据

  3. 子类在初始化之前. 一定要调用父类构造方法先完成父类数据空间的初始化

  4. 如何调用父类中的构造方法?

  • 子类构造方法的第一行默认都是:super(), 不写也存在, 且必须在第一行

3. 多态

3.1 多态的定义

  1. 同类型的对象, 表现出的不同形态, 比如Person可以具化为Student, Teacher
    使用父类型作为参数, 可以接受所有子类对象

  2. 多态的表现形式: 父类类型 对象名称 = 子类对象;

  3. 多态的前提:
    (1) 有继承关系
    (2) 有父类引用指向子类对象
    (3) 有方法重写

3.2 多态调用成员的特点

先找父类中有没有
调用成员变量的特点: 编译看左边, 运行也看左边
调用成员方法的特点: 编译看左边, 运行看右边
image

3.3 多态的优势和缺点

  1. 优势:
    (1) 在多态中, 右边对象可以实现解耦合, 便于扩展和维护
    (2) 方法中, 使用父类型作为参数, 可以接收子类所有对象

  2. 缺点:
    不能使用子类的特有功能, 需要使用强制类型转换, 转换类型与真实对象类型不一致会报错
    转换的时候使用instanceof关键字进行判断

4. 包

4.1 包定义

  1. 包就是文件夹, 用来管理各种不同功能的Java类, 方便后期代码维护

  • 使用同一个包中的类时, 不需要导包
  • 使用java.lang包中的类时, 不需要导包
  • 如果同时使用两个包中的同名类, 需要用全类名(即包名+类名)

5. final

final作用

  1. final修饰方法: 表明该方法是最终方法, 不能被重写

  2. final修饰类: 表明该类是最终类, 不能被继承

  3. final修饰变量: 叫做常量, 只能被赋值一次

  4. 常量的命名规范:
    (1) 单个单词: 全部大写
    (2) 多个单词: 全部大写, 单词之间用下划线隔开

  5. final 修饰的变量是基本类型: 那么变量存储的数据值不能发生改变
    final 修饰的变量是引用类型: 那么变量存储的地址值不能发生改变, 对象内部的可以改变

  6. 权限修饰符

  7. 权限修饰符: 是用来控制一个成员能被访问的范围的

  8. 可以修饰成员变量, 方法, 构造方法, 内部类
    image

7. 代码块

7.1 局部代码块(了解)

节约内存, 提前结束变量的生命周期
image

7.2 构造代码块(了解)

将构造方法重复代码抽取出来写到构造代码块中, 优先于构造方法执行, 但是不够灵活
image

7.3 静态代码块(重点)

  1. 格式: static{}
  2. 特点: 需要通过static关键字修饰, 随着类的加载而加载, 并且自动触发, 只执行一次
  3. 使用场景: 在类加载的时候, 做一些数据初始化的时候使用

8. 抽象类

8.1 抽象方法和抽象类

  1. 抽象方法: 将共性的行为抽取到父类之后, 由于每一个子类执行的内容是不一样的, 所以在父类中不能确定为具体的方法体
    该方法就可以定义为抽象方法, 强制子类必须重写该方法

  2. 抽象类: 如果一个类中存在抽象方法, 那么该类就必须声明为抽象类

  3. 抽象方法的定义格式: public abstract 返回值类型 方法名 (参数列表);
    抽象类的定义格式: public abstract class 类名{}
    意义是强制此类必须按照这种格式进行重写

  4. 抽象类不能实例化
    抽象类中不一定有抽象方法, 但是有抽象方法的一定是抽象类
    可以有构造方法, 作用是当创建子类对象时, 给属性赋值的
    抽象类中的子类: 要么重写抽象类中的所有抽象方法, 要么是抽象类

9. 接口

9.1 接口的定义和使用

  1. 接口就是一种规则

  2. 接口用关键字interface来定义: public interface 接口名{}

  3. 接口不能实例化, 接口和类之间是实现关系, 通过implements关键字来表示
    public class 类名 implements 接口名{}

  4. 接口的子类(实现类):

    • 要么重写接口中所有的抽象方法
    • 要么是抽象类
  5. 接口和类之间是实现关系, 可以单实现, 也可以多实现, 即 public class 类名 implements 接口名1, 接口名2{}
    接口和接口之间是继承关系, 可以单继承, 也可以多继承, 如果实现类实现了最下面的子接口, 那么就需要重写所有的抽象方法

  6. 实现类还可以在继承一个类的同时实现多个接口
    public class 类名 extends 父类 implements 接口名1, 接口名2{}

9.2 接口中成员的特点

  1. 成员变量: 只能是常量, 默认修饰符: public static final
  2. 没有构造方法
  3. JDK7及以前成员方法只能是抽象方法, 默认修饰符public abstract

9.3 JDK8以后接口中新增的方法(default, static)

02815d5ef96209fe11cf54fcdd573d2
c27c74024e2869842b81be5fd103950
5a1a0c940d0a7b66bb30bec3fe0d593
d44cad0dd422a5428b19321054f511a

9.4 JDK9新增的方法(私有方法)

46060112591af69eaaf4326922aa2ae
b7388f8766a146d1cd859955c196ee6
921b27d67a6dd2bebb6ed69a0d8829a

10. 内部类

10.1 内部类的定义

  1. 类的五大成员: 属性, 方法, 构造方法, 代码块, 内部类

  2. 在一个类的里面, 再定义一个类, 内部类表示的事物是外部类的一部分, 内部类单独出现没有任何意义, 比如汽车的发动机

  3. 内部类的访问特点:

    • 内部类可以直接访问外部类的成员, 包括私有
    • 外部类要访问内部类的成员, 必须创建对象

10.2 内部类的分类

10.2.1 成员内部类(了解)

  1. 写在成员位置的, 属于外部类的成员(类中方法外, 没有static修饰)

  2. 获取成员内部类对象的两种方式
    (1) 外部类编写方法, 对外提供内部类对象(成员内部类被private修饰)
    (2) 直接创建
    Outer.Inner oi = new Outer.new Inner();
    image

  3. 成员内部类如何获取外部类的成员变量(Outer.this.)
    image

10.2.2 静态内部类(了解)

  1. 是一种特殊的成员内部类, 静态内部类的创建格式: 外部类名.内部类名 对象名 = new 外部类名.内部类名();
    image
  2. 调用非静态方法的格式: 先创建对象, 用对象调用
  3. 调用静态方法的格式: 外部类名.内部类名.方法名();

10.2.3 局部内部类(了解)

  1. 将内部类定义在方法里面就叫做局部内部类, 类似于方法里面的局部变量
  2. 外界是无法直接使用的, 需要在方法内部创建对象并使用(考虑和方法中的局部变量类似)
  3. 该类可以直接访问外部类中的成员, 也可以访问方法内的局部变量

10.2.4 匿名内部类(重点)

  1. 当方法的参数是接口或者类时, 以接口为例, 可以传递接口这个的实现类对象, 如果实现类只需要使用一次, 就可以用匿名内部类简化代码
  2. 匿名内部类本质上就是隐藏了名字的内部类(只是不需要自己显示写名字), 真正的没有名字的类是大括号里面的, new 出来的本质还是对象
  3. new 后面的是接口就是实现关系, 是类就是继承关系
    image
    image
posted @ 2025-08-16 15:42  awei040519  阅读(8)  评论(0)    收藏  举报