1.基本概念
1.1面向对象VS面向过程
| 面向对象 | 关注对象,谁来做,做什么 | 代码模块化,复用性强,易拓展 |
| 面向过程 | 关注过程,先做什么,再做什么 | 代码线性,简单直接,复用性差、难维护 |
1.2核心概念-类和对象
·类:类是共同特征的描述-对象的模板
// 类的定义:class 类名 { 属性; 方法; 构造方法; } public class 类名 { // 1. 属性(成员变量):描述类的特征 数据类型 属性名; // 2. 构造方法:创建对象时初始化属性(与类名相同,无返回值) public 类名() { // 无参构造(默认会有,若写了带参构造,默认的会消失) } public 类名(参数列表) { // 带参构造:给属性赋值 this.属性名 = 参数; } // 3. 方法(成员方法):描述类的行为 返回值类型 方法名(参数列表) { 方法体; return 返回值; } }·对象:对象是真实存在的具体实例-类的实例
类名 对象名=new 类名();·类和对象的关系:类是模板,对象是模板造出来的成品。类只是模板,不会占用内存,对象是实际存在的实例,会占用内存。
·构造方法的作用:初始化对象的属性,没有返回值,名称必须和类名一致;如果没写构造方法,Java 会默认提供一个无参构造;如果写了带参构造,默认的无参构造会消失(建议手动补全无参构造)。
·this关键字:只能在类的方法 / 构造方法中使用,指代当前对象,用来区分成员变量和局部变量。
1.3核心特性-封装、继承和多态
封装:将数据和操作数据的方法绑定在一起,隐藏对象的属性和实现细节。
继承:子类可以继承父类的特征和行为,实现代码复用。
多态:允许不同类的对象对同一消息做出响应。
1.4标准的JavaBean类
1)类名需要见名知意
2)成员变量使用private修饰
3)提供至少两个构造方法-无参构造方法和带全部参数的构造方法
4)成员方法-提供给每一个成员变量对应的setXxx()和getXxx()
2.核心特性
访问修饰符:
| 修饰符 | 同一类中 | 同一包中 | 子类中 | 任意地方 |
|---|---|---|---|---|
| public | ✅ | ✅ | ✅ | ✅ |
| protected | ✅ | ✅ | ✅ | ❌ |
| default(默认,不写) | ✅ | ✅ | ❌ | ❌ |
| private | ✅ | ❌ | ❌ | ❌ |
2.1封装-给属性加安全锁
·封装的核心:隐藏对象的内部细节(属性私有化),只通过指定接口(get/set)暴露访问方式,从而控制访问权限,保证数据安全。
·封装的实现步骤:
1)使用private修饰属性(私有化属性,只能在当前类中进行访问)
2)提供public的get方法可以获取属性值
3)提供public的set方法可以修改属性值,在set中可以添加基本的逻辑验证
·封装的核心价值:安全性(避免非法数据)、可维护性(修改校验逻辑只需要修改set方法)
2.2继承-复用代码,少写重复逻辑
·继承的核心:子类(子模板)继承父类(父模板)的属性和方法,子类只需要写自己特有的属性和方法,实现代码的复用。
·继承的语法:
// 子类 extends 父类 public class 子类名 extends 父类名 { // 子类特有的属性和方法 }·核心知识点:
1)super关键字
作用:在子类中访问父类的属性、方法、构造方法
注意:super()(调用父类构造)必须写在子类的第一行,且只能出现一次
与this的区别:this指代的是当前对象,super指代的是父类对象
2)方法重写
子类对父类的方法进行重新实现,必须满足以下三个规则:
-方法名、参数列表和返回值类型必须完全与父类保持一致
-子类方法的访问权限不能低于父类
-用@Override注解可以验证是否符合重写规则
3)Java的继承规则
-单继承:一个子类只能有一个直接父类,不能同时继承两个
-多层继承:子类可以继承父类,父类可以再继承其他类
-子类不能继承父类的private属性/方法,但可以通过父类的public get/set访问
-所有类都默认继承Object类(Java的顶层父类)
2.3多态-同一行为,不同表现
·多态的核心:父类引用指向子类对象,调用方法时,实际执行的时子类重写之后的方法。
·多态的实现条件:-有继承关系 -子类重写父类方法 -父类引用指向其他子类
·方法重载(多态的另一种形式)
方法重载指的是同一个类中,方法名相同,但参数列表不同(个数,类型,顺序不同),与返回值无关
重载 vs 重写(易混淆点)
| 对比维度 | 重载(Overload) | 重写(Override) |
|---|---|---|
| 发生位置 | 同一类中 | 子类与父类之间 |
| 方法名 | 相同 | 相同 |
| 参数列表 | 不同(个数 / 类型 / 顺序) | 相同 |
| 返回值 | 无要求 | 必须与父类一致 |
| 访问权限 | 无要求 | 子类不能低于父类 |
| 核心作用 | 同一方法的不同参数形式 | 子类个性化实现父类方 |
3.内存图
每个软件在运行时都会占用一块内存,但是JVM将其分为五块区域-本地方法栈、寄存器、栈、堆、方法区。
在jdk7以前,堆和方法区是连在一起的,在真实的物理区域也是连续的。从jdk8开始,取消方法区,新增元空间,将原来方法区的多种功能进行拆分,有的功能放到了堆中,有的功能放到了元空间中。
方法区:字节码文件加载时进入的内存。
栈内存:方法运行时所进入的内存,变量也是在这里。
堆内存:new出来的东西会在这块内存中开辟空间并产生地址。
3.1一个对象的内存图
1)加载class文件
2)申明局部变量
3)在堆内存中开辟一个空间
4)默认初始化
5)显示初始化
6)构造方法初始化
7)将堆内存中的地址值赋值给左边的局部变量
eg.
3.2两个对象的内存图
创建两个对象的时候,在第一次创建对象时已经加载过class字节码文件,所以第二次创建对象的时候不需要再加载一次字节码文件了。
3.3两个引用指向同一个对象
3.4this的内存原理
this的作用:区分局部变量和成员变量。
this的本质:所在方法调用者的地址值。
4.基本数据类型和引用数据类型
基本数据类型:整数类型、浮点数类型、布尔类型、字符类型
引用数据类型:创建的任意对象、数组等都是字符串类型
基本数据类型和引用数据类型的区别:
基本数据类型中,数据值是存储在自己的空间中。-赋值给其他变量时,也是赋的真实值。
引用数据类型中,数据值存储在其他空间中,自己空间中存储的是地址值。-赋值给其他变量时,赋的是地址值。
5.成员变量和局部变量的区别
| 区别 | 成员变量 | 局部变量 |
|---|---|---|
| 类中的位置 | 类中,方法外 | 方法内,方法声明上 |
| 初始化值不同 | 有默认初始化值 | 没有,使用之前需要完成赋值 |
| 内存位置不同 | 堆内存 | 栈内存 |
| 生命周期不同 | 随着对象的创建而存在,随着对象的消失而消失 | 随着方法的调用而存在,随着方法运行结束而消失 |
| 作用域 | 整个类中有效 | 当前方法中有效 |