面向对象编程
- 面向对象的本质:以类的方式组织代码,以对象的方式组织(封装)数据
1 引用类型
- 引用类型:Java语言中除基本类型之外的变量类型
- Java中的对象是通过引用对其操作
2 类的属性
- 类的属性:该类包含的数据或静态属性(成员变量)
- 属性作用范围是整个类体
- 在定义成员变量时需要对其进行初始化,否则Java会使用默认值对其进行初始化
3 内存分析
- 栈(自动分配的连续的内存空间,后进先出):存放局部变量
- 堆(不连续的内存空间):存放new出来的对象
- 方法区(在堆内存中):存放类的信息(代码)、static变量、常量池(字符串常量)等
4 垃圾回收机制(Garbage Collection)
- 对象空间的分配
- 使用
new
关键字创建对象即可
- 使用
- 对象空间的释放
- 将对象赋值为
null
即可,垃圾回收器负责将所有“不可达”的对象内存空间进行回收
- 将对象赋值为
注:
1. 程序员无权调用垃圾回收器;
2. 程序员可以通过System.gc()
,通知GC运行,但是JVM并不能保证立刻执行垃圾回收;
3. finalize()
是Java提供的主动释放对象或资源的方法,但是不建议使用。
5 构造器(构造方法_Constructor)
- 功能:用于构造类的实例
- 作用:构造该类的对象,用于初始化对象的属性
- 构造器通过
new
关键字进行调用 - 构造器虽然没有返回值,但是不能定义返回类型
- 没有定义构造器时,编译器会自动创建该类的无参构造器
- 构造器的方法名必须与类名保持一致
6 重载(Overload)
-
两同三不同
- 同一个类,同一个方法名
- 不同:参数列表不同(类型,个数,顺序不同)
-
构造方法也可以构成重载
7 Static关键字
-
修饰变量:声明的成员变量转换成静态变量
static
变量在方法区中- 在类被载入时被显式初始化
-
修饰方法:声明的方法转换成静态方法
static
方法在方法区中- 不需要对象,可以直接调用(
类名.方法
) - 在调用该方法时,不会将对象的引用传递给它,所以在
static
方法中,不可以访问非static
的成员
-
static
初始化块- 如果希望加载后,对整个类进行某些初始化操作,可以使用
static
初始化块 - 类初始化时即执行,而不是在创建对象时执行
- 静态初始化块中,不能访问非
static
成员 - 执行顺序
- 上溯到
Object
类,先执行Object
的静态初始化块,再向下执行子类的静态初始化块
- 上溯到
- 如果希望加载后,对整个类进行某些初始化操作,可以使用
static{
System.out.println("static");
}
public static void main(String[] args) {
System.out.println("main");
}
8 this关键字
- 每个方法的在编译后都会传入一个
this
和super
的隐式函数,其中this
指向子类最终创建的对象,super
指向该类的直接父类(默认传入) - 普通方法中,
this
总是指向调用该方法的对象 - 构造方法中,
this
总是指向正要初始化的对象 this
不能用于static
方法
class computer {
public computer(int a) {
this(); // 调用没有参数的构造器,并且只能放在构造器的第一行
System.out.println("有参数的构造器");
}
public computer(){
System.out.println("没有参数的构造器");
}
}
9 面向对象的三大特征
-
继承(extends)
- 子类继承父类,不能继承父类的构造方法
- Java中的类只有单继承
- Java中的多继承可以通过接口实现
- 当一个类没有继承其他类时,其父类是
java.lang.Object
-
封装(encapsulation)
- 意义:隐藏对象内部的复杂性,之对外提供简单的接口,便于外界调用,提高可扩展性和可维护性
- 实现高内聚(类的内部数据细节外部不可干涉),低耦合(仅暴露少量的方法给外部使用)
- 类属性的处理
- 一般使用
private
(除非本属性确定会让子类继承) - 提供相应的get/set方法,访问相关的属性,这些方法通常是
public
,从而提供对属性的读取操作
- 一些只用于本类的辅助性方法可以用
private
,希望其他类调用的方法用public
同一个类 | 同一个包 | 子类 | 所有类 | |
---|---|---|---|---|
private | ~ | |||
Default | ~ | ~ | ||
Protected | ~ | ~ | ~ | |
Public | ~ | ~ | ~ | ~ |
- 多态(polymorphism)
- 程序的最终状态只有在执行该过程中才被决定而非在编译期间决定
- 引用变量的两种类型
- 编译时类型:由声明时的类型决定
- 运行时类型:由实际对应的对象类型决定
- 多态存在的必要条件
- 存在继承
- 存在方法的重写
- 父类引用指向子类对象
10 super关键字
super
关键字:直接父类对象的引用,可以通过super
来访问父类中被子类覆盖的方法或属性- 所有的构造器,第一句都是
super();
,如果没有显式的写出,编译时会自动追加
注:Object
类没有父类,所以该类没有super();
语句
public class demo01 {
public static void main(String[] args) {
son c = new son();
}
}
class father {
public father () {
super();
System.out.println("father");
}
}
class son extends father{
public son (){
super();
System.out.println("son");
}
}
// 以上运行结果
// father
// son
11 final关键字
- 修饰变量:常量,不能再次赋值
- 修饰方法:不能在子类中重写,但是可以被重载
- 修饰类:不能有子类,不能被继承
12 抽象类(abstract)
- 意义:将方法的设计和方法的实现进行分离,通过建立抽象类,可以避免子类设计的随意性
- 要点:
- 有抽象方法的类必须定义为抽象类
- 抽象类不能被实例化
- 抽象类可以包含属性、普通方法和构造方法,但是构造方法不能用来
new
实例,只能用来被子类调用 - 抽象类只能用来继承
- 抽象类中的抽象方法子类必须实现
13 接口(interface)
- 接口不能创建实例,但是可用于声明引用变量类型
- 一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是
public
的 - 接口支持多继承
14 回调——多态的应用(CallBack,钩子函数)
/**
* 钩子函数的测试
*
* @author Administrator
*
*/
public class HookTest {
public static void main(String[] args) {
getHook(new Hook());
getHook(new Hook01());
getHook(new Hook02());
}
public static void getHook(Hook hook){
hook.creatHook(); // 钩子函数,传入不同的子类,调用不同的creatHook()方法
}
}
class Hook {
public void creatHook() {
System.out.println("THIS IS HOOK");
}
}
class Hook01 extends Hook {
public void creatHook() {
System.out.println("THIS IS HOOK01");
}
}
class Hook02 extends Hook {
public void creatHook(){
System.out.println("THIS IS HOOK02");
}
}