二,面向对象
面向对象三大特征:封装,继承,多态
1. 封装
1.1 封装的定义
-
封装旨在:正确设计对象的属性和方法
-
对象代表什么, 就得封装对应的数据, 并提供数据对应的行为, 比如, 人画圆, 画圆的方法需要定义在圆中
1.2 构造方法
1.2.1 定义
-
构造方法也叫构造器,构造函数
-
作用是在创建对象时候给成员变量初始化

-
构造方法的定义
-
如果没有定义构造方法, 系统将给出一个默认的无参数构造方法
-
如果定义了构造方法, 系统将不再提供默认的构造方法
-
带参构造方法和无参构造方法属于方法的重载
1.2.2 this的内存原理

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

1.3 标准的JavaBean类
- 下在ptg插件, 可以调用生成构造方法

1.4 对象内存图(了解)
1.4.1 一个对象的内存图

main方法结束后释放堆内存
1.4.2 两个对象的内存图


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

1.5. Static
1.5.1 定义
-
static表示静态, 是Java中的一个修饰符, 可以修饰成员方法, 成员变量
-
被static修饰的成员变量叫静态变量, 被static修饰的成员方法叫静态方法
-
特点是被该类所有对象共享, 不属于对象而属于类, 调用方式两种:
- 类名调用(推荐)
- 对象名调用
-
静态方法多用在工具类和测试类中, JavaBean类中很少使用
-
三大类:
- JavaBean类: 用来描述一类事物的类, 比如Student, Dog, Cat
- 测试类: 用来检查其他类是否书写正确, 带有main方法的类, 是程序的入口
- 工具类(类名见名知意, 私有化构造方法, 方法定义为静态): 不是描述一类事物的, 而是帮助我们做一些事情的类
1.5.2 static内存图
- 静态变量是随着类的加载而加载的, 优先于对象出现的

1.5.3 static注意事项
-
静态方法只能访问静态方法和静态变量, 非静态方法没有限制
-
静态方法中没有this关键字
-
非静态方法中含有隐藏的this关键字, 不能自己赋, 而是有虚拟机赋值的
1.5.4 重新认识main
虽然调用函数是静态的, 但也可以在静态方法中创建对象使用非静态

2. 继承
2.1 继承的定义
- Java中提供一个关键字extends, 用这个关键字, 可以让一个类和另一个类建立起继承关系, 并可以创建自己的方法
// Student 称为子类(派生类), Person 称为父类(基类, 超类)
public class Student extends Person {}
2.2 继承的特点
-
Java只支持单继承(一个子类只能继承一个父类), 不支持多继承(子类不能同时继承多个父类), 但支持多层继承

-
Java中的类都直接或间接继承于Object类
2.3 子类继承的父类内容
-
成员变量都能继承

-
父类的构造方法不能被子类继承
-
只有父类中的虚方法才能被子类继承

2.4 继承的内存图
2.4.1 父类成员变量非私有
- 和以往不同的是, 加载字节码的文件时, 会把父类的字节码也加载下来, 创建对象时, 一部分存储本类的变量和方法, 另一部分存储父类的
object理应载入字节码, 但是方便起见, 没有展示
\
2.4.2 父类变量私有
- 私有的父类变量也可以继承, 但是不能直接调用

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

2.5 成员变量的访问特点
- super调用直接访问父类

2.6 方法的重写
-
当父类的方法不能满足子类现在的需求时, 需要进行方法重写
-
在继承体系中, 子类出现了和父类中一模一样的方法声明, 我们就称子类这个方法是重写的方法
-
@override重写注解
(1) @override是放在重写后的方法上, 校验子类重写时语法是否正确
(2) 加上注解后如果有红色波浪线, 表示语法错误
(3) 建议重写方法都加上@override注解, 代码安全, 优雅 -
方法的重写本质上是覆盖虚方法表中继承的方法
2.7 构造方法的访问特点
-
父类中的构造方法不会被子类继承, 但是子类可以通过super调用
-
子类中的所有构造方法默认先访问父类中的无参构造, 再执行自己
这是因为子类在初始化的时候, 有可能会用到父类中的数据, 如果父类没有完成初始化, 子类将无法使用父类的数据 -
子类在初始化之前. 一定要调用父类构造方法先完成父类数据空间的初始化
-
如何调用父类中的构造方法?
- 子类构造方法的第一行默认都是:super(), 不写也存在, 且必须在第一行
3. 多态
3.1 多态的定义
-
同类型的对象, 表现出的不同形态, 比如Person可以具化为Student, Teacher
使用父类型作为参数, 可以接受所有子类对象 -
多态的表现形式: 父类类型 对象名称 = 子类对象;
-
多态的前提:
(1) 有继承关系
(2) 有父类引用指向子类对象
(3) 有方法重写
3.2 多态调用成员的特点
先找父类中有没有
调用成员变量的特点: 编译看左边, 运行也看左边
调用成员方法的特点: 编译看左边, 运行看右边

3.3 多态的优势和缺点
-
优势:
(1) 在多态中, 右边对象可以实现解耦合, 便于扩展和维护
(2) 方法中, 使用父类型作为参数, 可以接收子类所有对象 -
缺点:
不能使用子类的特有功能, 需要使用强制类型转换, 转换类型与真实对象类型不一致会报错
转换的时候使用instanceof关键字进行判断
4. 包
4.1 包定义
-
包就是文件夹, 用来管理各种不同功能的Java类, 方便后期代码维护
- 使用同一个包中的类时, 不需要导包
- 使用java.lang包中的类时, 不需要导包
- 如果同时使用两个包中的同名类, 需要用全类名(即包名+类名)
5. final
final作用
-
final修饰方法: 表明该方法是最终方法, 不能被重写
-
final修饰类: 表明该类是最终类, 不能被继承
-
final修饰变量: 叫做常量, 只能被赋值一次
-
常量的命名规范:
(1) 单个单词: 全部大写
(2) 多个单词: 全部大写, 单词之间用下划线隔开 -
final 修饰的变量是基本类型: 那么变量存储的数据值不能发生改变
final 修饰的变量是引用类型: 那么变量存储的地址值不能发生改变, 对象内部的可以改变
-
权限修饰符
-
权限修饰符: 是用来控制一个成员能被访问的范围的
-
可以修饰成员变量, 方法, 构造方法, 内部类

7. 代码块
7.1 局部代码块(了解)
节约内存, 提前结束变量的生命周期

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

7.3 静态代码块(重点)
- 格式: static{}
- 特点: 需要通过static关键字修饰, 随着类的加载而加载, 并且自动触发, 只执行一次
- 使用场景: 在类加载的时候, 做一些数据初始化的时候使用
8. 抽象类
8.1 抽象方法和抽象类
-
抽象方法: 将共性的行为抽取到父类之后, 由于每一个子类执行的内容是不一样的, 所以在父类中不能确定为具体的方法体
该方法就可以定义为抽象方法, 强制子类必须重写该方法 -
抽象类: 如果一个类中存在抽象方法, 那么该类就必须声明为抽象类
-
抽象方法的定义格式: public abstract 返回值类型 方法名 (参数列表);
抽象类的定义格式: public abstract class 类名{}
意义是强制此类必须按照这种格式进行重写 -
抽象类不能实例化
抽象类中不一定有抽象方法, 但是有抽象方法的一定是抽象类
可以有构造方法, 作用是当创建子类对象时, 给属性赋值的
抽象类中的子类: 要么重写抽象类中的所有抽象方法, 要么是抽象类
9. 接口
9.1 接口的定义和使用
-
接口就是一种规则
-
接口用关键字interface来定义: public interface 接口名{}
-
接口不能实例化, 接口和类之间是实现关系, 通过implements关键字来表示
public class 类名 implements 接口名{} -
接口的子类(实现类):
- 要么重写接口中所有的抽象方法
- 要么是抽象类
-
接口和类之间是实现关系, 可以单实现, 也可以多实现, 即 public class 类名 implements 接口名1, 接口名2{}
接口和接口之间是继承关系, 可以单继承, 也可以多继承, 如果实现类实现了最下面的子接口, 那么就需要重写所有的抽象方法 -
实现类还可以在继承一个类的同时实现多个接口
public class 类名 extends 父类 implements 接口名1, 接口名2{}
9.2 接口中成员的特点
- 成员变量: 只能是常量, 默认修饰符: public static final
- 没有构造方法
- JDK7及以前成员方法只能是抽象方法, 默认修饰符public abstract
9.3 JDK8以后接口中新增的方法(default, static)




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



10. 内部类
10.1 内部类的定义
-
类的五大成员: 属性, 方法, 构造方法, 代码块, 内部类
-
在一个类的里面, 再定义一个类, 内部类表示的事物是外部类的一部分, 内部类单独出现没有任何意义, 比如汽车的发动机
-
内部类的访问特点:
- 内部类可以直接访问外部类的成员, 包括私有
- 外部类要访问内部类的成员, 必须创建对象
10.2 内部类的分类
10.2.1 成员内部类(了解)
-
写在成员位置的, 属于外部类的成员(类中方法外, 没有static修饰)
-
获取成员内部类对象的两种方式
(1) 外部类编写方法, 对外提供内部类对象(成员内部类被private修饰)
(2) 直接创建
Outer.Inner oi = new Outer.new Inner();

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

10.2.2 静态内部类(了解)
- 是一种特殊的成员内部类, 静态内部类的创建格式: 外部类名.内部类名 对象名 = new 外部类名.内部类名();

- 调用非静态方法的格式: 先创建对象, 用对象调用
- 调用静态方法的格式: 外部类名.内部类名.方法名();
10.2.3 局部内部类(了解)
- 将内部类定义在方法里面就叫做局部内部类, 类似于方法里面的局部变量
- 外界是无法直接使用的, 需要在方法内部创建对象并使用(考虑和方法中的局部变量类似)
- 该类可以直接访问外部类中的成员, 也可以访问方法内的局部变量
10.2.4 匿名内部类(重点)
- 当方法的参数是接口或者类时, 以接口为例, 可以传递接口这个的实现类对象, 如果实现类只需要使用一次, 就可以用匿名内部类简化代码
- 匿名内部类本质上就是隐藏了名字的内部类(只是不需要自己显示写名字), 真正的没有名字的类是大括号里面的, new 出来的本质还是对象
- new 后面的是接口就是实现关系, 是类就是继承关系



浙公网安备 33010602011771号