面向对象 - Object Oriented Programming
===========================================
* 问题分解
* 一个个独立的小问题,单独解决
类
===========================================
* 对事物、逻辑、概念、算法等的抽象
* 理解为: 图纸
* 一个类,在java类型系统中是一种新的数据类型
* 类中抽象事物的:
* 属性(数据)
* 方法(行为)
对象(实例)
===========================================
* 从类,创建出的具体实例
* 理解为: 根据图纸生产出的产品
引用
===========================================
* 引用变量,保存一个实例的内存首地址
* 通过引用变量,可在内存中找到这个实例,
并访问其成员
* 理解为: 遥控器
* 特殊值: null
不保存任何实例的内存地址
空引用
构造方法
===========================================
* 任何类都有构造方法
* 创建实例时执行的一个特殊方法
new Solider() -- 执行构造方法
new Solider(191) -- 执行有参数的构造方法
* 如果不编写任何构造方法,
编译器会添加默认构造方法: 公共无参构造方法
public Solider() {}
* 构造方法一般用来为成员变量赋初值,
* 根据逻辑需要,可在构造方法中编写任何代码
成员变量
局部变量
=================================================
成员变量
------------------------------
* 类内
* 作用域:类内
* 有默认值,数字0,布尔值false,引用类型null
局部变量
------------------------------
* 方法、局部代码块内
* 作用域:代码块内
* 必须初始化(手动赋值)
* 允许与成员变量重名
this
=======================================================
* 特殊引用,记录当前实例的内存首地址
* 同过 this,可访问当前实例的成员
this.x
this.y
this.distance()
* 在构造方法中,调用其他构造方法;
必须是构造方法首行代码;
目的:代码重用
this();
this(参数1,参数2...,)
访问控制符
===========================================
类 包 子类 任意
public O O O O
protected O O O
[default] O O
private O
* 访问控制符使用原则
尽量隐藏
* 所有公开的成员、公开的类应保持稳定
* 私有成员可任意修改、删除,不会对其他程序造成损害
重载 - Override
===================================
* 同名不同参
* 构造方法也可重载
* 同过参数区分方法
参数传递
===================================
* 传值
*) 基本类型值就是数值本身
*) 引用类型值是实例的内存首地址
* 方法返回,也是返回变量的值
继承 extends
===================================
* 一个类,从另一个类继承写过的代码
* 目的: 代码重用
* 单继承:
只能继承一个父类
创建子类实例:
===================================
1) 创建父类实例
2) 创建子类实例
* 两个实例绑定在一起,整体看做是子类实例
* 当调用一个成员时:
1) 在子类实例中寻找此成员
2) 子类中没有,在父类实例中寻找此成员
方法重写(覆盖,Override)
===================================
* 从父类继承的方法不满足子类需要时,
在子类中重写此方法
* 方法覆盖规则:
*) 方法签名(返回类型、方法名、参数列表)必须与父类中方法一致
*) 访问范围不能降低
*) 抛出的异常不能更多
super
===================================
* 创建子类实例的时,先创建父类实例;
创建父类实例也要执行它的构造方法
* 在子类构造方法中,调用父类构造方法
super(); // 调用父类无参构造方法
super(参数1,参数2,参数3...); // 调用父类有参构造方法
* 在子类构造方法中,默认执行父类无参构造方法:
super();// 默认
* 父类中如果不存在无参构造方法,
必须显示调用父类中有参构造方法
* super() 调用,必须是构造方法的首行代码
----------
* 通过 super.xxx() 调用父类的成员方法
多态
===================================
* 子类实例,可以被当做父类类型来处理
* 向上转型,自动
*) 子类实例转为父类型
*) 向上转型后,隐藏了子类中扩展的成员,
只能访问父类定义的通用成员
* 向下转型,强制
“被转为父类型的子类实例”,转回成子类型
* 多态的好处:
以一致的方式,处理多种不同子类型对象
运行期类型识别 instanceof
---------------------------------------
* 程序执行过程中,识别其类型
s instahceof Line
-- 左侧引用,所指向的实例,是否是 Line 类型
* 对实例类型及其父类型判断,都会返回 true
Shape s = new Line();
s instanceof Line -- true
s instanceof Shape -- true
后期绑定(运行期绑定、动态绑定)
----------------------------------------------
* 编译时,方法调用不会和一段具体代码直接绑定在一起
* 运行时,在实例中动态寻找此方法的代码,找到后绑定执行
* 静态成员
私有成员
成员变量
都是在前期绑定
面向对象语言特征
=================================================
* 封装
相关属性、行为、方法、逻辑、算法,
写成一个类
* 继承
代码复用
什么时候使用继承:
-------------------------
* 继承是程序结构复杂
* 占用更多资源、降低效率
* 存在 is a 关系时才用继承
* 多态
static
========================================
* 静态
* 修饰类中的成员
* 静态成员属于类
非静态成员属于实例
* 应使用类名调用静态成员
*) 也允许使用实例来调用,但可读性差
* 静态代码块内,不能调用实例的成员,不能使用 this 关键字
* static 什么时候使用?
-----------------------------------------
* 原则: 能不用就不用
* static 是非面向对象的
* 共享的数据(减少内存占用)
Math.PI
Math.E
* 工具类工具方法(方便调用)
Math.random()
Math.sqrt()
初始化块
========================================
* 静态初始化块(常用)
*) 在类加载时,只执行一次
* 非静态初始化块(不常用)
*) 在每次实例创建时执行,先于构造方法
静态初始化块用处:
--------------------------------
* 事先加载一些资源
在界面中显示的图片、
网络连接、
连接数据库
对象创建的过程
========================================
class A {
int n1 = 10;
static int n2 = 11;
static {
...
}
}
class B extends A {
int n3 = 12;
static int n4 = 13;
static {
...
}
}
B b = new B();
-------------------------------------
第一用到 B 类时:
1) 加载父类 A
2) 为 A 类的静态成员变量分配内存
3) 加载子类 B
4) 为 B 类的静态成员变量分配内存
5) 为 A 类的静态变量执行赋值运算
6) 执行 A 类的静态初始化块
7) 为 B 类的静态变量执行赋值运算
8) 执行 B 类的静态初始化块
每次创建实例时:
9) 为父类 A 的实例变量分配内存
10) 为子类 B 的实例变量分配内存
11) 为 A 类的实例变量执行赋值运算
12) 执行 A 类的构造方法
13) 为 B 类的实例变量执行赋值运算
14) 执行 B 类的构造方法
final
========================================
* 修饰三种:
变量 - 变量一旦初始化,它的值不可变,称为常量
方法 - 在子类中不能重写这个方法,父类中的方法是最终版本
类 - 不能有子类
* 一般使用 static final 声明常量
* 常量
命名规则: 全大写,单词间用下划线隔开
Double.MAX_VALUE
* 编译期和运行期,都会进行优化
byte b1 = 2;
byte b2 = 3;
byte b3 = b1 + b2; // 错
byte b4 = 2 + 3; // 对,编译器优化为:byte b4 = 5;
----
final byte b1 = 2;
final byte b2 = 3;
byte b3 = b1 + b2; // 对,编译器优化为:byte b4 = 5;
抽象类
========================================
* 半成品类,理解为:一张未完成的图纸
* 抽象方法:
*) 没有方法体
*) 添加 abstract 关键字
* 含抽象方法的类必须是抽象类
* 抽象类不能创建实例
* 抽象类作用:
---------------------------
*) 为子类提供通用代码
*) 为子类定义统一的方法规约
* 实现类必须实现抽象类中定义的抽象方法
接口
========================================
* 极端的抽象类
* 程序结构设计工具
* 用于解耦合
用法:
----------------------------
* 接入可替换的组件
* 接口隔离,解耦合
接口语法
----------------------------
*) 定义接口:
public interface A {}
*) 实现接口:
class Xxxx implements A {}
class Xxxx implements A,B,C {}
class Xxxx extends Parent implements A,B,C {}
*) 接口之间继承
public interface A extends B {}
public interface A extends B,C {}
*) 接口内部只能定义:
1) 抽象方法
可省略两个关键字: public abstract
2) 常量
可省略三个关键字: public static final
3) 内部类或内部接口
===========================================
* 问题分解
* 一个个独立的小问题,单独解决
类
===========================================
* 对事物、逻辑、概念、算法等的抽象
* 理解为: 图纸
* 一个类,在java类型系统中是一种新的数据类型
* 类中抽象事物的:
* 属性(数据)
* 方法(行为)
对象(实例)
===========================================
* 从类,创建出的具体实例
* 理解为: 根据图纸生产出的产品
引用
===========================================
* 引用变量,保存一个实例的内存首地址
* 通过引用变量,可在内存中找到这个实例,
并访问其成员
* 理解为: 遥控器
* 特殊值: null
不保存任何实例的内存地址
空引用
构造方法
===========================================
* 任何类都有构造方法
* 创建实例时执行的一个特殊方法
new Solider() -- 执行构造方法
new Solider(191) -- 执行有参数的构造方法
* 如果不编写任何构造方法,
编译器会添加默认构造方法: 公共无参构造方法
public Solider() {}
* 构造方法一般用来为成员变量赋初值,
* 根据逻辑需要,可在构造方法中编写任何代码
成员变量
局部变量
=================================================
成员变量
------------------------------
* 类内
* 作用域:类内
* 有默认值,数字0,布尔值false,引用类型null
局部变量
------------------------------
* 方法、局部代码块内
* 作用域:代码块内
* 必须初始化(手动赋值)
* 允许与成员变量重名
this
=======================================================
* 特殊引用,记录当前实例的内存首地址
* 同过 this,可访问当前实例的成员
this.x
this.y
this.distance()
* 在构造方法中,调用其他构造方法;
必须是构造方法首行代码;
目的:代码重用
this();
this(参数1,参数2...,)
访问控制符
===========================================
类 包 子类 任意
public O O O O
protected O O O
[default] O O
private O
* 访问控制符使用原则
尽量隐藏
* 所有公开的成员、公开的类应保持稳定
* 私有成员可任意修改、删除,不会对其他程序造成损害
重载 - Override
===================================
* 同名不同参
* 构造方法也可重载
* 同过参数区分方法
参数传递
===================================
* 传值
*) 基本类型值就是数值本身
*) 引用类型值是实例的内存首地址
* 方法返回,也是返回变量的值
继承 extends
===================================
* 一个类,从另一个类继承写过的代码
* 目的: 代码重用
* 单继承:
只能继承一个父类
创建子类实例:
===================================
1) 创建父类实例
2) 创建子类实例
* 两个实例绑定在一起,整体看做是子类实例
* 当调用一个成员时:
1) 在子类实例中寻找此成员
2) 子类中没有,在父类实例中寻找此成员
方法重写(覆盖,Override)
===================================
* 从父类继承的方法不满足子类需要时,
在子类中重写此方法
* 方法覆盖规则:
*) 方法签名(返回类型、方法名、参数列表)必须与父类中方法一致
*) 访问范围不能降低
*) 抛出的异常不能更多
super
===================================
* 创建子类实例的时,先创建父类实例;
创建父类实例也要执行它的构造方法
* 在子类构造方法中,调用父类构造方法
super(); // 调用父类无参构造方法
super(参数1,参数2,参数3...); // 调用父类有参构造方法
* 在子类构造方法中,默认执行父类无参构造方法:
super();// 默认
* 父类中如果不存在无参构造方法,
必须显示调用父类中有参构造方法
* super() 调用,必须是构造方法的首行代码
----------
* 通过 super.xxx() 调用父类的成员方法
多态
===================================
* 子类实例,可以被当做父类类型来处理
* 向上转型,自动
*) 子类实例转为父类型
*) 向上转型后,隐藏了子类中扩展的成员,
只能访问父类定义的通用成员
* 向下转型,强制
“被转为父类型的子类实例”,转回成子类型
* 多态的好处:
以一致的方式,处理多种不同子类型对象
运行期类型识别 instanceof
---------------------------------------
* 程序执行过程中,识别其类型
s instahceof Line
-- 左侧引用,所指向的实例,是否是 Line 类型
* 对实例类型及其父类型判断,都会返回 true
Shape s = new Line();
s instanceof Line -- true
s instanceof Shape -- true
后期绑定(运行期绑定、动态绑定)
----------------------------------------------
* 编译时,方法调用不会和一段具体代码直接绑定在一起
* 运行时,在实例中动态寻找此方法的代码,找到后绑定执行
* 静态成员
私有成员
成员变量
都是在前期绑定
面向对象语言特征
=================================================
* 封装
相关属性、行为、方法、逻辑、算法,
写成一个类
* 继承
代码复用
什么时候使用继承:
-------------------------
* 继承是程序结构复杂
* 占用更多资源、降低效率
* 存在 is a 关系时才用继承
* 多态
static
========================================
* 静态
* 修饰类中的成员
* 静态成员属于类
非静态成员属于实例
* 应使用类名调用静态成员
*) 也允许使用实例来调用,但可读性差
* 静态代码块内,不能调用实例的成员,不能使用 this 关键字
* static 什么时候使用?
-----------------------------------------
* 原则: 能不用就不用
* static 是非面向对象的
* 共享的数据(减少内存占用)
Math.PI
Math.E
* 工具类工具方法(方便调用)
Math.random()
Math.sqrt()
初始化块
========================================
* 静态初始化块(常用)
*) 在类加载时,只执行一次
* 非静态初始化块(不常用)
*) 在每次实例创建时执行,先于构造方法
静态初始化块用处:
--------------------------------
* 事先加载一些资源
在界面中显示的图片、
网络连接、
连接数据库
对象创建的过程
========================================
class A {
int n1 = 10;
static int n2 = 11;
static {
...
}
}
class B extends A {
int n3 = 12;
static int n4 = 13;
static {
...
}
}
B b = new B();
-------------------------------------
第一用到 B 类时:
1) 加载父类 A
2) 为 A 类的静态成员变量分配内存
3) 加载子类 B
4) 为 B 类的静态成员变量分配内存
5) 为 A 类的静态变量执行赋值运算
6) 执行 A 类的静态初始化块
7) 为 B 类的静态变量执行赋值运算
8) 执行 B 类的静态初始化块
每次创建实例时:
9) 为父类 A 的实例变量分配内存
10) 为子类 B 的实例变量分配内存
11) 为 A 类的实例变量执行赋值运算
12) 执行 A 类的构造方法
13) 为 B 类的实例变量执行赋值运算
14) 执行 B 类的构造方法
final
========================================
* 修饰三种:
变量 - 变量一旦初始化,它的值不可变,称为常量
方法 - 在子类中不能重写这个方法,父类中的方法是最终版本
类 - 不能有子类
* 一般使用 static final 声明常量
* 常量
命名规则: 全大写,单词间用下划线隔开
Double.MAX_VALUE
* 编译期和运行期,都会进行优化
byte b1 = 2;
byte b2 = 3;
byte b3 = b1 + b2; // 错
byte b4 = 2 + 3; // 对,编译器优化为:byte b4 = 5;
----
final byte b1 = 2;
final byte b2 = 3;
byte b3 = b1 + b2; // 对,编译器优化为:byte b4 = 5;
抽象类
========================================
* 半成品类,理解为:一张未完成的图纸
* 抽象方法:
*) 没有方法体
*) 添加 abstract 关键字
* 含抽象方法的类必须是抽象类
* 抽象类不能创建实例
* 抽象类作用:
---------------------------
*) 为子类提供通用代码
*) 为子类定义统一的方法规约
* 实现类必须实现抽象类中定义的抽象方法
接口
========================================
* 极端的抽象类
* 程序结构设计工具
* 用于解耦合
用法:
----------------------------
* 接入可替换的组件
* 接口隔离,解耦合
接口语法
----------------------------
*) 定义接口:
public interface A {}
*) 实现接口:
class Xxxx implements A {}
class Xxxx implements A,B,C {}
class Xxxx extends Parent implements A,B,C {}
*) 接口之间继承
public interface A extends B {}
public interface A extends B,C {}
*) 接口内部只能定义:
1) 抽象方法
可省略两个关键字: public abstract
2) 常量
可省略三个关键字: public static final
3) 内部类或内部接口