# 前言:
面向对象与面向过程的比较:
面向过程注重流程中的每一个细节,流程的发起者也是执行者 -
自己动手执行
面向对象注重于寻找对象,只要找到了对象,就能拥有这个对象的一切功能 -
找别人代干
如果事务相对简单,使用面向过程效率会相对较高;如果事务相对复杂,那么建议使用面向对象 -
分工合作
面向对象是基于面向过程
类与对象的关系:
类是对象的概括,对象是类的实例化
属性是一种特征,方法是一种行为
对象的内存存储
对象是存储在堆内存;在堆内存中会自动给属性赋予默认值
对象在栈内存中存储的是引用,所以在传值的时候传递的也是地址
成员变量和局部变量:定义位置、内存存储、生命周期
构造方法:
特点:与类同名,没有返回值类型
作用:用于创建对象
如果一个类中没有手动定义构造方法,默认会添加一个无参构造;如果手动定义了,在编译的时候就不添加了
构造方法可以重载
构造方法中可以出现return语句 - 用于校验数据以避免非法数据传入
this关键字:
表示当前的类在活动的对象的引用,可以认为是一个虚拟对象
在类外通过对象来调用方法或者属性,在类内用this来代替对象
this语句 - 在本类的构造方法中调用本类其他形式的构造方法 -
this语句必须放在构造方法的首行
代码块
构造代码块/初始化代码块:在类内用{}括起来的代码 -
在创建对象的时候,先于构造方法执行 - 如果无论调用哪个构造方法,都有一些行为需要执行,那么提取到构造代码块中
局部代码块:在方法中用{}括起来的代码 -
缩短变量的声明周期以提高栈内存的利用率
面向对象的特征:封装、继承、多态
封装:
形式:方法、类 - 属性的私有化,内部类
作用:提高代码的复用性/利用率;保证数据的合理性
# 权限修饰符
用于限制属性或者方法的使用范围的修饰符
**本类中** **子类中** **同包类中** **其他类中**
public 可以 可以 可以 可以
protected 可以 可以 可以 不可以
默认 可以 同包子类可以 可以 不可以
private 可以 不可以 不可以 不可以
# 继承
如果一些类中有一些公有的行为和特征,那么这个时候可以将这些类中的公有的行为和特征提取到一个新的类中,然后利用extends关键字让原来的类和新的类产生联系,这种关系称之为继承
类是对对象的抽取,继承实际上是对类的抽取
子类通过继承可以使用父类中的部分的方法和属性
注意:子类通过继承,可以继承父类全部的方法和属性,但是只有部分方法和属性对子类是可见的,所以子类也只能使用这一部分可见的方法和属性
在Java中,支持的是类和类之间的单继承 - 一个子类只能有一个父类,但是一个父类可以有多个子类
单继承和多继承的优劣性比较:多继承相对单继承而言,能够更有效的提高代码的复用性;如果多个类中出现了方法签名一致的方法,那么此时多继承会产生调用混乱问题
Java中采用单继承的优势:提高代码的复用性;有效避免方法调用的混乱
# super关键字
在子类中调用父类中的方法或者属性,可以认为是父类的虚拟对象
super语句 - 如果在子类的构造方法中没有指定super语句,那么默认会添加一个无参的super语句,实际上就是调用父类中的无参构造 --- super语句必须放在子类构造方法的第一行 --- 在创建对象的时候一定是先创建父类然后创建子类
# 方法的重写
如果在父子类中,存在了方法签名一致的非静态方法,那么就称这俩方法构成了重写/覆盖
方法重写的原则 - 两等两小一大:
方法签名一致的非静态方法
子类重写的方法的权限修饰符的范围要大于等于父类对应方法的权限修饰符的范围
如果父类方法的返回值类型是基本类型/void,那么子类方法的返回值类型必须和父类方法的返回值类型一致
如果父类方法的返回值类型是引用类型,那么子类方法的返回值类型要么和父类方法的返回值类型一致,要么子类方法的返回值类型是父类方法返回值类型的子类
# 多态
编译时多态:方法的重载
add(2,5) --- add(int, int)
add(2,4,8) --- add(int ,int, int)
运行时多态:方法的重写和向上造型 --- 继承是运行时多态的前提
向上造型创建的对象 --- 只能调用父类中定义的属性或者方法不能调用子类中单独的定义的属性或者方法
# static - 静态
修饰符 --- 修饰变量、方法、代码块以及内部类
# 静态变量
static修饰的变量称之为静态变量/类变量。静态变量在类加载的时候加载到方法区,并且在方法区进行初始化。静态变量先于对象出现,也因此实际过程中,一般不是通过对象而是通过类名来调用静态变量。所有对象存储的是该静态变量的地址,所以静态变量是被所有对象所共享的
System.out System.in
注意:
类加载到方法区
类只在第一次被使用的时候加载
在加载的时候静态要先于非静态加载
{width="5.357638888888889in"
height="2.6180555555555554in"}
静态变量能否在方法中定义? - 不可以 - 从时间角度考虑,静态变量在类加载的时候进行初始化,方法中的变量在方法被调用的时候初始化;从空间角度考虑,静态变量加载到方法区,方法在栈内存中执行,方法中的变量都是存在栈内存中
静态变量能否定义在构造代码块中? - 不可以
注意:静态变量只能定义在类中
# 静态方法
用static修饰的方法称之为静态方法/类方法。静态方法在类加载的时候加载到方法区,只是存储在方法区,而没有执行。在静态方法被调用的时候到栈内存中执行。静态方法也是先于对象出现的,所以习惯上也是通过类名来调用静态方法
main Arrays.sort(),Arrays.toString(),Math.sqrt(),System.arraycopy(),Arrays.copyOf()
静态方法一般出现在了工具类中
静态变量能否定义在静态方法中? - 不能
静态方法中能否使用this/super? - 不能 - this代表了当前对象,静态方法先于对象存在
静态方法中能否直接使用非静态方法? - 不能 - 非静态方法是通过对象调用 - 静态中不能直接使用非静态
静态方法能否重载? - 可以
静态方法能否重写? - 不能 - 如果父子类中出现了方法签名一致的静态方法,那么称构成了静态方法的隐藏(hide) - 如果父子类中出现了方法签名相同的方法,要么都是静态,要么都是非静态 - 隐藏是一种编译时多态
# 静态代码块
只在类加载的时候执行一次 --- 类只加载一次,所以静态代码块也只执行一次