前言:写给自己,坚持不易,希望保持这股劲一直向前走
面向对象开发
面向对象程序设计(Object Oriented Programming,OOP)
- 把软件系统看成各种对象的集合
- 系统结构较稳定
- 子系统相对独立
- 软件可重用性、可维护性和可扩展性强
一、类与对象
1.面向对象程序设计
程序设计的过程,就是设计类的过程
万物皆对象,程序来源生活,只不过是抽象化–现实的类抽象化
人类:java程序中的类
人:Java中具体的对象
姓名,年龄等等:java中对象的属性特征,静态描述
吃饭,睡觉:Java中对象的方法,动态行为
2.类和对象的关系
类是对象的抽象,而对象是类的具体实例
类:具有相同属性和方法的一组对象的集合
实际类是不存在,只是用来分类,描述对象所具有的信息,而对象是看得见,摸得着的具体实例
属性:
描述对象的静态特征
方法:
描述对象的行为、操作(动态特征)
对象:
用来描述客观事物的一个实体,由一组属性和方法构成
3.类的定义
定义类的步骤:
(1)定义类名
(2)编写类的属性
(3)编写类的方法
注意:
类的属性和方法,一般都是同时存在的,不可分割的
类是java程序的最小组织单元。
示例:
public class 类名(首字母大写) {
// 定义属性部分(属性不能重名,有默认值)
属性类型(不仅仅基本数据类型)属性名称1;
属性类型(不仅仅基本数据类型)属性名称2;
// 定义方法部分
public void 方法名1(){
// 方法体
}
public void 方法名2(){
// 方法体
}
}
4.创建对象
语法:
类名 对象名 = new 类名();
School center = new School();
每个对象的属性和方法都是相互独立的,互不干涉
引用对象成员:使用“.”进行以下操作
引用类的属性:对象名.属性
引用类的方法:对象名.方法名()
center.name = "南京xz"; //给name属性赋值
center.showCenter(); //调用showCenter()方法
小练习:实现积分回馈功能
要求:
金卡客户积分大于1000分或普卡客户积分大于5000,获得回馈积分500分
创建客户对象,给对象的积分属性赋值,调用回馈积分方法输出卡基本信息及得到的回馈积分
根据题意,判断所要写的属性
//卡类
String type;
//积分
int integral;
定义输出方法
public void repay(Card card){
System.out.println("积分:" + card.integral + ",卡类型:" + card.type);
if ("金卡".equals(card.type)) {
if (card.integral > 1000) {
System.out.println("回馈积分500分!");
card.integral += 500;
System.out.println("回馈后积分为:" + card.integral);
}else {
System.out.println("积分未超过1000,无法回馈积分!");
}
}else if ("普卡".equals(card.type)) {
if (card.integral > 5000) {
System.out.println("回馈积分500分!");
card.integral += 500;
System.out.println("回馈后积分为:" + card.integral);
}else {
System.out.println("积分未超过5000,无法回馈积分!");
}
}else {
System.out.println("输入卡类型无效!");
}
}
测试类:
public class CardTest {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Card userCard = new Card();
System.out.print("请输入您的卡类型:");
userCard.type = input.next();
System.out.print("请输入您的卡内积分:");
userCard.integral = input.nextInt();
userCard.repay(userCard);
input.close();
}
}
二、方法与方法重载
1.类的无参方法
方法是什么?
方法是个“黑匣子”,完成某个特定的应用程序功能,并返回结果 类的方法定义类的某种行为(或功能)
如何定义一个方法?
// 方法名:(1)驼峰命名规则(2)有意义
public 返回值类型 方法名() {
//这里编写方法的主体
}
方法的返回值
如果方法具有返回值,方法中必须使用关键字return返回该值,返回值类型为该值的类型
其中:返回值只能有一个
没有返回值的方法,也可以使用return,作用是结束方法调用,返回方法调用处
方法调用
方法之间允许相互调用,不需要知道方法的具体实现,实现重用,提高效率
2.类的带参方法
定义带参数的方法
<访问修饰符> 返回类型 <方法名>(<形式参数列表>) {
//方法的主体
}
调用带参数的方法
对象名.方法名(参数1, 参数2,……,参数n)
注意:
形参需要指定参数的类型,参数类型和参数名空格分隔,形参只在方法内部可见,不需要初始化,因为其作用是接收调用方法的实际参数
带参方法传递参数时候,参数的类型和顺序要跟定义的形参列表保持一致
实参要有实际的含义,如果相同类型的参数,值顺序传递错误,那对应的方法执行的结果就是错误的
3. 方法参数传递
1)值传递
基本数据类型,操作传递的是变量的值,改变一个变量的值不会影响另一个变量的值
2)引用传递(地址传递)
引用数据类型(类、数组、集合等),赋值是把原对象的引用(可理解为内存地址)传递给另一个引用
4.构造方法
语法:
访问修饰符 构造方法名(){
//初始化代码
}
或者
访问修饰符 构造方法名(参数类型1 参数名1, 参数类型2 参数名2 。。。。){
//初始化代码
}
特点:
无返回值类型,方法名和类名相同,可以指定参数
作用:
创建对象初始化使用,系统会自动提供默认无参构造方法
自定义构造方法
- 方法名相同
- 参数项不同
- 与返回值、访问修饰符无关
此时系统不再提供默认无参构造方法
5.成员变量和局部变量
变量声明的位置决定变量的作用域,变量的作用域是变量可在程序中按照变量名访问的范围
语法:
public class 类名{
变量1类型 变量1;
变量2类型 变量2;
变量3类型 变量3;
public 返回类型 方法1(){
变量4类型 变量4;
}
public 返回类型 方法2(){
变量5类型 变量5;
}
}
for循环举例,循环内定义的变量,在循环外是无法直接访问的
示例:
for(int a = 0; a < 4; a++) {
System.out.println ("hello" );
}
System.out.println ( a );// 编译报错
6.两种变量的区别
作用域不同:
成员变量作用域在整个类内,而局部变量仅限于方法内
初始值不同:
成员变量有初始值,而局部变量不会赋予初始值
注意:
方法内不能有重名的局部变量,不同方法内可以定义同名的变量,同一个类中,成员和局部变量重名,那局部变量优先级高,使用this区分成员变量和局部变量,实现属性赋值操作
7.方法重载
方法重载特点:
- 同一个类中
- 方法名相同
- 参数个数或类型不同
- 与返回值、访问修饰符无关
8.this关键字的用法
- this关键字代表当前创建的对象
this.属性 操作当前对象的属性
this.方法 调用当前对象的方法。 - 封装对象的属性的时候,经常会使用this关键字。
- 构造方法中使用this必须遵守的规则:
(1)假如在一个构造方法中使用了this语句,那么它必须作为构造方法的第一条语句(不考虑注释语句)。
(2)只能在一个构造方法中使用this语句来调用类的其他构造方法,而不能在成员(实例)方法中用this语句来调用类的其他构造方法。
(3)只能用this语句来调用其他构造方法,而不能通过方法名来直接调用构造方法。
三、封装与继承
1.什么是封装
将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问
封装的步骤:
- 修改属性的可见性
改为private(防止错误修改属性值) - 创建公有的(public)getter和setter方法
方便对私有的属性进行赋值和读取 - 在getter和setter方法内,增加属性控制逻辑语句
对属性赋值或者读取进行合法的判断处理
封装的好处:
- 隐藏实现细节,方便修改
- 便于使用者正确使用系统,防止错误修改属性
- 有助于系统之间的松耦合,提高系统独立性
- 提高软件的可重用性
- 降低了构建大型系统的风险
2.访问权限控制
类的访问权限控制
public修饰符:公有访问级别
默认修饰符:包级私有访问级别
不同包,使用默认修饰符修饰的类,不可以跨包使用
访问修饰符
四个关键字:
private,默认(default,friendly),protected,public
访问权限范围从小到大,即安全性从高到低
3.static关键字
一句话描述:
方便在没有创建任何对象的前提下,可以直接通过类进行访问(属性或者方法)
static可以用来修饰
-
成员变量
静态变量,可以直接通过类名访问
-
成员方法
静态方法,可以直接通过类名访问
-
代码块
静态代码块,当Java虚拟机加载类时,就会执行该代码块
注意:
static代码块,可以出现在类的任何地方,类内可以有多个static代码块
static代码块,在类加载的时候,会按照static块的先后顺序进行执行,且只会执行一次。
static变量
类的成员变量包括
- 类变量(静态变量)
- 被static修饰的变量
- 在内存中只有一个拷贝
- 类内部,可在任何方法内直接访问静态变量
- 其他类中,可以直接通过类名访问
- 实例变量
- 没有被static修饰的变量
- 每创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响
static变量的作用:
(1)能被类的所有实例共享,可作为实例之间进行交流的共享数据
(2)如果类的所有实例都包含一个相同的常量属性,可把这个属性定义为静态常量类型,从而节省内存空间
类变量(static修饰的成员变量)和实例变量的区别
1)被static修饰的变量,在内存中只有一个拷贝,类内部,可在任何方法内直接访问静态变量,其他类中,可以直接通过类名访问
2)没有被static修饰的变量,每创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响。
static方法
- 静态方法:可直接通过类名访问
- 静态方法中不能使用this和super
- 不能直接访问所属类的实例变量和实例方法
- 可直接访问类的静态变量和静态方法
- 实例方法:通过实例访问
- 可直接访问所属类的静态变量、静态方法、实例变量和实例方法
- 静态方法必须被实现
类方法(static修饰的成员方法)和实例方法的区别
1)静态方法中不能使用this和super,不能直接访问所属类的实例变量和实例方法,可直接访问类的静态变量和静态方法
2)可直接访问所属类的静态变量、静态方法、实例变量和实例方法
归纳:非静态方法可以访问静态属性和方法,但是反过来不成立
static代码块
JVM加载类时,加载静态代码块
- 如果有多个静态块,按顺序加载
- 每个静态代码块只会被执行一次
4、继承的用法
- 语法:
编写父类
[访问修饰符] class Pet {
//公共的属性和方法
}
编写子类
[访问修饰符] class Dog extends Pet {
//子类特有的属性和方法
}
注意:
子类和父类要存在is-a的关系
使用的继承关键字为:extends,类和类之间只能存在单继承,即只能继承一个类,同一个类可以被多个子类继承
-
访问父类的成员:
关键字:super,代表父类的对象子类访问父类的构造:
super()或者super(参数)子类访问父类的属性:
super.属性子类访问父类的方法:
super.方法()注意:
1)super关键字只能出现在存在继承关系的子类中,且只能在方法或者构造方法中
2)在子类构造方法中,super关键字调用父类的构造,只能在第一句
3)不可以通过super关键字访问父类的private属性或者方法
继承条件下,子类继承规则:
-
子类构造方法没有通过super显式调用父类的有参构造方法,也没通过this显式调用自身其他构造方法,系统默认调用父类的无参构造方法
-
子类构造方法通过super显式调用父类的有参构造方法执行父类相应构造方法,而不执行父类无参构造方法
5、子类可以继承父类的内容
1)继承public和protected修饰的属性和方法,不管子类和父类是否在同一个包里
2)继承默认权限修饰符修饰的属性和方法,但子类和父类必须在同一个包里
父类不可以被子类继承的内容:
1)父类的私有成员(属性和方法)-- private修饰的
2)子类和父类不在同包下面,父类使用默认修饰符修饰的成员
3)子类不能继承父类的构造方法(构造是跟类紧密关联的,方法名不同,有特殊用法,用户创建实例)
6、何时使用继承:
1)是否存在is-a的关系,存在就可以用
2)继承的使用条件
子类是特殊的类型,不代表是父类的角色
子类是父类的扩展,可以包含子类特有的属性和方法,且不能让父类的功能失效
四、方法重写与多态
1、方法重写
1.1、意义
当子类继承父类方法,但是父类的方法功能无法满足子类的需求,那就需要在子类重新定义父类的方法,加入子类需要的内容,这种就是方法重写
1.2、方法重写或方法的覆盖(overriding)
- 子类对所继承父类相同方法的一种更改,这个更改需要遵循格式按照父类的格式,访问权限,抛出异常等等,都在父类方法控制范围内,内部具体实现可以实现不同的效果。
- 重写时,可以用super.方法的方式来保留父类的方法
- 构造方法由于类名不同,所以不能被继承,也就不能被重写
- 方法重写的前提是:必须要存在继承的关系。
备注:
String字符串的equals方法就是最明显的重写,toString()也是
使用的注解:@override,存在继承关系,可以直接写要重新方法名,自动会带出重写的方法,注意,如果加了注解,代表必须是重写方法
2、方法重写的规则
1)方法重写时,方法名与形参列表必须一致。
2)方法重写时,子类的返回值类型相同或者是其子类,即必须要小于或者等于父类的返回值类型。
3)方法重写时,子类的权限修饰符不能严于父类,即要大于或者等于父类的权限修饰符。
4)方法重写时,父类的静态方法不能被子类覆盖为非静态方法,父类的非静态方法不能被子类覆盖为静态方法
5)方法重写时,子类可以定义与父类同名的静态方法,以便在子类中隐藏父类的静态方法(注:静态方法中无法使用super)
6)方法重写时,父类的私有方法不能被子类覆盖
7)方法重写时,子类抛出的异常类型要小于或者等于父类抛出的异常类型。
3、方法重载和方法重写的异同
4、Object类
所有类的父类,如果没有使用extends关键字指定基类,那默认是继承object类
Object类被子类经常重写的方法:
Object类的equals()方法
比较两个对象是否是同一个对象,是则返回true
操作符==
- 简单数据类型,直接比较值。如1==2
- 引用类型,比较两者是否为同一对象
(1)Object类的equals()方法与==没区别
(2)当有特殊需求,如认为属性相同即为同一对象时,需要重写equals()
(3)Java.lang.String重写了equals()方法,把equals()方法的判断变为了判断其值
5、多态
1.什么是多态
定义:
同一个行为,具有多个不同形式的表现或者能力
2.为什么使用多态
没使用多态的弊端:
频繁修改代码,代码的扩展性、可维护性差
同一个方法,可能需要针对不同的类型参数,重复定义
3.如何实现多态
使用多态实现思路
-
编写具有继承关系的父类和子类
-
子类重写父类方法
-
使用父类的引用指向子类的对象
向上转型
Pet pet = new Dog(); // 自动类型转换
向上转型
//测试方法
Pet pet = new Dog();
pet.setHealth(20);
Master master = new Master();
master.cure(pet);
向上转型:父类的引用指向子类对象,自动进行类型转换
<父类型> <引用变量名> = new <子类型>();
- 此时通过父类引用变量调用的方法是子类覆盖或继承父类的方法,不是父类的方法
- 此时通过父类引用变量无法调用子类特有的方法
向下转型
如果需要调用子类特有的方法,怎么办?
Dog dog=(Dog)pet;//将pet 转换为Dog类型
dog. catchingFlyDisc();//执行Dog特有的方法
向下转型:将一个指向子类对象的父类引用赋给一个子类的引用,即:父类类型转换为子类类型。需强制类型转换
<子类型> <引用变量名> = (<子类型> )<父类型的引用变量>;
在向下转型的过程中,如果没有转换为真实子类类型,会出现类型转换异常
如何减少在向下转型的过程中,没有转换为真实子类类型的类型转换异常?
Java中提供了 instanceof 运算符来进行类型的判断
使用instanceof时,对象的类型必须和instanceof后面的参数所指定的类在继承上有上下级关系
实现多态的两种形式:
1)父类作为方法形式参数
2)父类作为方法的返回值
父类指向子类对象时:
注意:
- 通过父类引用变量调用的方法是子类覆盖的方法
- 通过父类引用变量调用的方法是子类未覆盖的,调用的是从父类继承的旧方法
- 通过父类引用变量无法调用子类特有的方法(父类没有该方法,所以调用不到)
- 属性也类似
子类引用指向自身对象时:
注意:
- 子类引用变量调用的方法是子类覆盖的方法
- 子类引用变量调用的方法是未覆盖的,实际调用的是从父类继承的旧方法
- 子类引用变量可以调用子类特有的方法
- 属性也类似
五、抽象类与接口
1、抽象类和抽象方法
抽象类和抽象方法都使用关键字:abstract修饰
抽象类写法:
[修饰符] abstract class 类名{
...
}
抽象方法写法:
public abstract void 方法名();
注意:
方法修饰符不能为private,默认是public
使用规则:
1)抽象方法没有方法体,直接分号结尾,主要给子类进行重写
2)抽象方法必须定义在抽象类里,即:抽象方法所在的类必须是抽象类,但是抽象类可以没有抽象方法
3)子类继承抽象类,抽象方法必须在子类中被实现,除非子类是抽象类
4)没有抽象构造方法,也没有抽象静态方法(语法冲突)
5)抽象类中可以有普通构造方法,创建子类的实例时可能调用,也可以有普通方法
6)抽象类不能创建实例,因为可能包含抽象方法
7)抽象类可以作为类型使用,指向子类的实例,调用其抽象方法实际是子类重写的方法
2、什么是接口
接口(英文:Interface),在JAVA中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口并不是类,跟类属于不同的概念:类描述对象的属性和方法。接口则包含要实现的方法(能力)。
一个类实现接口,除非是抽象类,否则该类要实现接口中的所有方法,否则编译不通过
3、语法
使用interface关键字,代表定义的为接口
语法:
[修饰符] interface 接口名称 [extends 父接口名,可以多个,逗号分隔] {
[public] [static] [final] 常量; //全局常量
[public] [abstract] 方法; //抽象方法
}
4、特性
1)接口不可以被实例化,长作为类型使用
2)实现类必须实现接口的所有方法
3)实现类可以实现多个接口,implements、多个接口以逗号分隔
4)接口中的变量都是静态常量-接口中的变量会被隐式地指定为public static final变量(并且只能是public static final变量,用private修饰会报编译错误)
5)接口中的方法都是公共public,抽象的abstract,且只能是public abstract方法(用其他关键字,比如private、protected、static、final等修饰会报编译错误)所以一般都不需要再声明,写了也不会报错,但是代码检查会提示多余
6)注意:接口是java中解决多继承的有效手段
5、接口的使用
以usb接口为例:
定义接口
/**
* USB接口。
*/
public interface UsbInterface {
/**
* USB接口提供服务。
*/
void service();
}
定义U盘实现接口
/**
* U盘。
*/
public class UDisk implements UsbInterface {
public void service() {
System.out.println("连接USB接口,进行数据传输。");
}
}
定义Usb风扇:
/**
* USB风扇。
*/
public class UShan implements UsbInterface{
public void service() {
System.out.println("连接usb接口,通电,风扇开始转起来。");
}
}
6、接口代表一种能力
能力体现在不同的方法上,它关心的是实现类实现的接口能力,但是不关心具体的实现细节
接口体现的是一种规范和实现分离的设计哲学,充分利用接口可以极好地降低程序各模块之间的耦合,从而提高系统的可扩展性和可维护性
接口是一种能力
接口有比抽象类更好的特性:可以被多继承、设计和实现完全分离、更自然的使用多态、更容易搭建程序框架、更容易更换实现
接口是一种约定
我们知道了这个约定,直接使用就可以,而不需要关心它是如何实现的,一般我们定义接口名要根据功能来直译,然后添加详细的方法注释,这样我们看到接口就知道自己要用的方法
7、抽象类和接口的异同
相同点:
代表系统的抽象层,都不能被实例化,都能包含抽象方法-用于描述系统提供的服务,不必提供具体实现
不同点:
抽象类和接口区别-抽象方法只能存在于抽象类或者接口中,但抽象类中却能存在非抽象方法,即有方法体的方法。接口是百分之百的抽象类
语法层面上的区别:
1)抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;
2)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
3)接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
4)一个类只能继承一个抽象类,而一个类却可以实现多个接口。
设计层面上的区别:
抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象
设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计(只需要改模板即可)。而接口是一种行为规范,它是一种辐射式设计(接口一旦修改,所有实现类都要修改)
8、抽象类和接口的使用原则
接口做系统与外界交互的窗口-接口提供服务,接口本身一旦制定,就不允许随意修改
抽象类可完成部分功能实现,还有部分功能可作为系统的扩展点
9、面向对象设计原则
1)多用组合,少用继承
继承会继承父类的内容,有些我们不需要的内容也会继承过来,但是组合不会,使用组合就可以按照需要调用,只有真正存在is a的关系才选择使用继承,否则使用组合
2)针对扩展开放,针对改变(修改)关闭
针对扩展开发:就是需求变动,需要增加功能,少修改原有已经实现的功能模块代码,而是新建模块进行扩展,一般我们修改已经实现的代码基本会是代码有bug,
针对修改关闭:就是要把核心的,共性的,不会被修改的内容抽离,直接使用,不会动这部分的代码
3)针对接口编程-合理、高效使用接口
六、异常
1、异常定义
异常是指在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序.
异常处理:
Java编程语言使用异常处理机制为程序提供了错误处理的能力
2、异常处理关键字
try 执行代码,可能出现异常的逻辑代码块
catch 异常捕获,可以针对可能出现的异常,进行特殊处理
finally 无论是否发生异常,都会执行的代码块,除了特殊场景不执行(System.exit(1))
throw 手动抛出异常(一般是自定义异常,自己不处理,让调用该方法的代码块处理,配合throws使用)
throws 声明方法可能抛出的多个异常,多个异常用逗号分隔
3、try…catch…finally用法
使用try-catch块捕获异常,分为三种情况:
第一种情况 :正常
public void method(){
try {
// 代码段(此处不会产生异常)
} catch (异常类型 ex) {
// 对异常进行处理的代码段
}
// 代码段
}
第二种情况:出现异常
public void method(){
try {
// 代码段 1
// 产生异常的代码段 2
// 代码段 3
} catch (异常类型 ex) {
// 对异常进行处理的代码段4
}
// 代码段5
}
第三种情况:异常类型不匹配
public void method(){
try {
// 代码段 1
// 产生异常的代码段 2
// 代码段 3
} catch (异常类型 ex) {
// 对异常进行处理的代码段4
}
// 代码段5
}
- 在catch块中处理异常
加入用户自定义处理信息
System.out.println("出现错误:被除数和除数必须是整数 ");
- 调用方法输出异常信息
e.printStackTrace();
- 异常对象常用的方法
常见的异常类型
在try-catch块后加入finally块
- 是否发生异常都执行
- 不执行的唯一情况
存在return的try-catch-finally块
public void method(){
try {
// 代码段 1
// 产生异常的代码段 2
} catch (异常类型 ex) {
// 对异常进行处理的代码段3
return;
}finally{
// 代码段 4
}
}
当异常处理代码块中存在return,会先执行finally,然后再执行return(因为finally是不管是否发生异常,都不行运行的代码块,唯一特殊情况是:System.exit())
4、throws和throw的用法
throws场景:
声明接口时,定义可能存在的异常对象,给调用接口方处理
当方法内不想处理异常的时候,可以往外层抛出该异常,留给方法调用者处理
处理方式:
调用者使用try。。catch捕获处理
调用者继续向外层抛出该异常
throw场景:
一般用于自定义异常,针对特有的业务逻辑,增加异常信息,方便业务实现
二者区别:
1)throws出现在方法的声明中,在形参列表后,而throw只能出现在方法内部
2)throws代表可能抛出的异常,但是不一定会发生,但是throw是手动抛出异常,该异常是在特定业务场景下,必须存在的异常
3)throws声明的是抛出异常类型,可以是多个,但是throw是抛出一个具体的异常对象,只能是一个。
4)throws和throw一般是相互配合使用的
5、异常的分类
运行时异常
代码运行过程中,可能存在的异常,编译器编译代码是正常的,不会报错
ArrayIndexOutOfBoundsException
NullPointerException
ClassCastException
NumberFormatException
InputMismatchException
ArithmeticException
检查异常
必须要处理的异常,且不处理就不能编译通过
比如:ClassNotFoundException,FileNotFoundException,IOException,SQLException等
注意:
系统错误Error不是异常,这个不是代码可以处理的,一般是非程序异常
异常体系结构
6、自定义异常
- 当JDK 中的异常类型不能满足程序的需要时,可以自定义异常类
- 使用自定义异常的步骤
步骤:
- 定义异常类,继承Exception或者RuntimeException
- 编写构造方法,调用父类的相应构造
- 实例化自定义异常对象
- 通过throw关键字抛出异常
异常处理原则
-
异常处理与性能
-
异常只能用于非正常情况
-
不要将过于庞大的代码块放在try中
-
在catch中指定具体的异常类型
-
需要对捕获的异常做处理