Java面向对象思想
- 面向对象语言三大基本特征:封装(数据抽象),继承,多态;
- 封装的目的在于绝对不允许类中方法直接访问其它类的实例域,程序仅通过对象的方法与对象的数据进行交互;封装赋予”对象“黑盒特征,提高重用性和可靠性;
- 对象变量本质是指向一个对象/实例的引用(reference),Java通过引用操作对象;
- Java通过new在堆上创建对象,对象变量实质是指向对应堆对象的引用;
- 一个对象引用可以指向0个或1个对象(不指向对象时被垃圾回收机制回收);
- 一个对象可以被N个引用指向它(N>=1);
- Java类中所有方法都必须在类内部定义(C++可在类外部定义方法);
- 返回一个可变对象的引用时,应首先对其进行克隆(clone);
Java传参机制
在Java中,方法参数共有两种类型:
- 基本数据类型(call by value,传值调用),方法得到基本数据类型的拷贝,不能修改参数变量;
- 对象引用(call by value,传值调用),方法得到对象引用的拷贝,
- 该拷贝和对象引用同时引用同一个对象,方法可以通过引用拷贝修改对象参数的“状态”;
- 该拷贝改变引用对象时,方法无法对象参数的“状态”;
static方法/static变量/static块
- static含义:属于类并且不属于类对象的函数/变量;
- static修饰的方法 = 类方法 = 静态方法,用类名直接访问,不可用this调用;
- static方法不可访问非静态方法(因为直接访问等同于用this关键字调用实例方法);
- static修饰的变量 = 类变量 = 静态变量,类变量与所在类生命周期相同;
- static变量/方法也可用实例对象访问(不推荐),同一个类的所有实例访问类变量时,访问了同一片内存区,故类变量可理解为所有实例对象的“全局变量”;(注:即使某个实例为null,仍然可以访问所属类的static方法/static变量)
- 每一个类可拥有一个main方法,常用于类单元测试;
成员变量与局部变量
- 定义局部变量后,系统并没有分配对应内存空间,直到变量赋初值时,系统才会为局部变量分配内存;
- 使用局部变量时,局部变量的作用范围↓—>局部变量驻留内存时间↓
访问控制符private/包访问/protected/public
访问控制权限:private<包访问权限(不加任何访问控制符)<protected<public,控制级别从小到大
private | 包访问权限 | protected | public | |
当前类内部 | √ | √ | √ | √ |
同一包下其他类 | √ | √ | √ | |
子类 (不考虑包位置) | √ | √ | ||
全局范围 | √ |
- 如果Java源文件.java内定义的所有类都没有用public修饰,源文件名任意;
- 每个.java文件中有且只能有一个public类,且源文件名必须与该public类名相同;
- 类中只用于辅助实现类中其他方法的工具方法,应用private修饰;
- 类中希望暴露给其他类自由调用的方法用public修饰,比如类构造器;
- 类中方法定义顺序依次为:public, protected, private, getter/setter方法
构造器/Constructor
Person wall = new Person(); // 构造器Person()负责创建实例对象wall?
调用构造器前,系统事先为该实例对象分配内存空间,并执行默认初始化;
—>此时的实例对象不可被外部访问,只能在构造器中通过this引用;
当构造器执行接收后,构造器返回实例对象给另一个引用类型变量;
—>外部可访问实例对象;
构造器返回值:
- 构造器形式上没有返回值,因此不可用return语句;
- 构造器实质上返回类的实例,隐式返回;
构造器重载:
- 类中没有提供任何构造器的时候,系统提供默认构造器;
- 同一个类中具有多个构造器,对应形参列表不同;
初始化块/initialization block
- 对象初始化块:每次创建实例对象时,先于构造器前执行初始化块,;
- static初始化块:仅在所在类加载时,执行static块;
初始化顺序
- 类加载时,
- 执行static部分初始化(仅在加载类时运行一次);
- static块和static成员变量直接赋值语句,根据定义顺序先后执行;
- 使用new创建对象,堆上分配对象内存,对应基本类型赋值默认值,对象引用赋值null;
- 执行所有成员变量直接赋值语句,对象初始化块,根据定义顺序先后执行;
- 执行构造器;
finalize方法/终结方法
极力避免使用finalize方法销毁对象;
应用场合:当在Java程序中,采用“本地方法”(在Java中调用非Java代码,目前仅支持C/C++)申请内存可能会造成内存泄露,此时使用finalize()方法显示回收对象;
使用finalize方法销毁对象性能低下;