【笔记】面向对象 学习笔记
前言
面向对象编程(oop)学习笔记
类 对象
- 现实世界是由很多很多对象组成的
- 基于对象抽出了类
概念
- 对象:真实存在的单个的个体
- 类:类型/类别,代表一类个体
类中可以包含
- 成员变量
所有对象所共有的属性/特征
- 方法
所有对象所共有的行为
特点
- 一个类可以创建多个对象
- 同一类型所创建的对象,结构相同,数据不同
- 类是对象的模板,对象是类的具体的实例
方法
方法的签名
- 方法名+参数列表
方法的重载
- 发生在一个类中,方法名称相同,参数列表不同,方法体不同
- 编译器在编译时会根据方法的签名自动绑定调用的方法
参数列表类型相同数量不同
1 | public void method(int... nums) { |
构造方法
构造函数、构造器,构建器
- 给成员变量赋初值
- 与类同名,没有返回值类型
- 在创建对象时自动调用构造方法
- 若自己不写构造方法,则编译器默认一个无参构造方法
- 若自己写了构造方法,则不再默认提供
- 构造方法可以重载
this
指代当前对象,哪个对象调用方法它指的就是哪个对象
只能用在方法中,方法中访问成员变量之前默认有个this.
this的用法
访问成员变量
1 | this.成员变量名 |
调用方法(一般不用)
1 | this.方法名() |
调用构造方法
1 | this() |
null
空,没有指向任何对对象
若引用的值的null,则该引用不能再进行任何操作了
若操作则发生NullPointerException空指针异常
引用类型变量
- 指向同一个对象
- 通过一个引用对数据的修改会影响另一个引用对数据的访问
基本类型变量
- 赋值
- 对一个变量的修改不会影响另一个变量
引用类型数组
继承
作用
- 代码复用
实现
- 通过
extends
来实现继承
属性行为范围
- 超类/父类:所有派生类所共有的属性和行为
- 派生类/子类:派生类所特有的属性和行为
- 派生类继承超类后,派生类具有:派生类的+超类的
特点
一个超类可以有多个派生类
一个派生类只能有一个超类(单一继承)
具有传递性
规定
构造派生类之前必须先构造超类
在派生类的构造方法中若自己不调用超类的构造方法,则默认`super()调用超类的无参构造方
在派生类的构造方法中若自己调用了超类的构造方法,则不再默认提供
super()
- 调用超类构造方法,必须位于派生类构造的第一行
super
- 指代当前对象的超类对象
super的用法
访问超类的成员变量
访问超类的成员变量
1 | super.成员变量名 |
调用超类的方法
1 | super.方法名() |
调用超类的构造方法
1 | super() |
向上造型
- 超类型的引用指向派生类的对象
- 能点出来什么,看引用的类型
方法的重写
重新写、覆盖
- 发生在父子类中,方法名相同,参数列表相同,方法体不同
- 重写方法被调用时,看对象的类型
遵循原则
- 遵循”两同两小一大”原则
两同
- 方法名称相同
- 参数列表相同
两小
- 派生类方法的返回值类型小于或等于超类方法的
void
时,必须相等
基本类型时,必须相等
引用类型时,小于或等于
- 派生类方法抛出的异常小于或等于超类方法的
一大
- 派生类方法的访问权限大于或等于超类方法的
package
作用
- 避免类的命名冲突
特点
- 包名可以有层次结构,同包中的类不能同名
类的全称
1 | 包名.类点 |
建议
- 包名所有字母都小写
import
- 同包中的类可以直接访问
- 不同包中的类不能直接访问,想访问有如下两种方式
先import声明类再使用类
类的全称
访问控制修饰符
public
:公共的,任何类protected
:受保护的,本类、派生类、同包类
默认的:什么也不写,本类、同包类private
:私有的,本类
- 类的访问修饰符只能是
public
和默认的 - 类中成员的访问修饰符如上4种都可以
final
- 最终的、不可改变的
修饰变量
- 变量不能被改变
修饰方法
- 方法不能被重写
修饰类
- 类不能被继承
static
- 静态的
静态变量
- 由
static
修饰 - 属于类,存储在方法区中,一份
- 常常通过类名点来访问
- 何时用:所有对象所共享的数据(图片、音频、视频等)
静态方法
- 由
static
修饰 - 属于类,存储在方法区中,一份
- 常常通过类名点来访问
- 静态方法没有隐式的this传递,
- 静态方法不能直接访问实例成员
- 何时用:方法的操作仅与参数相关而与对象无关
静态块
- 属于类的,在类被加载期间自动执行,
- 因类只被加载一次,所以静态块只执行一次
- 何时用:加载/初始化静态资源(图片、音频、视频等)
常量
1 | static final |
- 必须声明同时初始化
- 类名点来访问,不能被改变
- 建议:常量名所有字母都大写,多个单词由
_
分隔 - 编译器在编译时将常量直接替换为具体的值,效率高
- 何时用:数据永远不变,并且经常使用
抽象方法
- 由
abstract
修饰 - 只有方法的定义,没有具体的实现
抽象类
- 由abstract修饰
- 包含抽象方法的类必须是抽象类
- 不包含抽象方法的类也可以声明为抽象类
- 抽象类不能被实例化
继承关系
- 抽象类是需要被继承的
重写所有抽象方法
也声明为抽象类
抽象类的意义
- 封装派生类共有的属性和行为(代码复用)
- 为所有派生类提供统一的类型(向上造型)
- 可以包含抽象方法,为所有派生类提供统一的入口,派生类的具体行为不同,但入口是一致的
成员内部类
- 类中套类,外面的称为Outer外部类,里面的称为Inner内部类
- 内部类通常只服务于外部类,对外不具备可见性
- 内部类对象通常是在外部类中创建的
- 内部类中可以直接访问外部类的成员(包括私有的)
- 内部类中有个隐式的引用指向了创建它的外部类对象
匿名内部类
- 若想创建一个类(派生类)的对象,并且对象只被创建一次,此时该类不必命名,称为匿名内部类
jdk1.7
及之前,想访问匿名内部类外面的变量,该变量必须是final的
接口
- 是一种数据类型(引用类型)
- 由interface定义
- 只能包含常量和抽象方法
- 不能被实例化
- 接口是需要被实现/继承的,实现类/派生类 必须重写接口中的所有抽象方法
- 一个类可以实现多个接口,用逗号分隔,若又继承又实现时,应先继承后实现
- 接口可以继承接口(多个)
多态
意义
- 同一类型的引用,指向不同的对象时,有不同的实现
- 同一个对象,被造型为不同的类型时,有不同的功能
向上造型
自动类型转换
- 超类型的引用指向派生类的对象
- 能造型成为的数据类型有: 超类+所实现的接口
- 能点出来什么,看引用的类型
强制类型转换
引用所指向的对象,就是该类型
引用所指向的对象,实现了该接口或继承了该类
强转时若不符合如上条件,则发生ClassCastException类型转换异常
建议:强转之前先通过instanceof判断引用指向的对象是否是该类型
参考文献
达内学习视频