第二章 面向对象
Java是一种面向对象的语言,像同样的编译语言,比如:c语言,则是一种面向过程的语言。
举个例子理解,比如“做饭”:
面向过程:我要买菜,我要洗菜,我要切菜,我要炒菜,我要装盘,我要吃...
面向对象:我要做的是:“吃”,其他的交给别人来做。
面向过程注重的是以过程为核心,所有的事情要亲力亲为的去实现,而面向对象则是以结果为中心,不需要每件事都自己去做,核心就是找到能干这件事的正确的对象。
那对象是如何表达呢?
对象则是属性和方法的集合。
任何一个对象都有两个属性,静态属性和动态属性,例如:一只小狗,它的名字,颜色,品种,年龄都是它的静态属性,而这只小狗会跑,会跳,会叫则是它的动态属性。
由此我们可以得知:静态属性就是描述一个对象固定的属性(属性),动态属性则是描述这个对象能干什么(方法)。
如果有两只小狗,一只是金毛,而另一只是二哈,这时候我们就发现这两只小狗有一些共同的属性和行为(方法),我们可不可以把这些属性和行为(方法)集合起来呢?
答案当然是可以的,为了使程序员方便调用,我们可以把具有相同属性和行为的对象进行抽取,抽取成一个类。
类:是一种抽象的概念,有属性和方法构成,具有相同属性和行为的对象的抽取。
对象:实实在在存在的个体,值得是一群人,一个群体,具有相同属性和行为的对象的抽取。
Class - - - 类
先声明一个类
属性,方法
通过类来创建对象
使用对象来调用属性和方法
明确的说只有对象才能调用方法。
总结:
对象:用来描述客观事物的一个实体,由一组属性(静态特征)和方法(动 态特征)构成;
属性:用来描述对象的固有特征,一般是名词;
方法:用来描述对象的动作,这个对象能干嘛,一般是动词;
重点:
类和对象的关系?
类是抽象的,对象是具体的。
类是具有相同属性和行为(方法)的集合。
对象是类的一个实例,是一个具体的实体。
方法的参数
方法:方法可以直接调用当前类的属性,
方法五要素:访问修饰符、方法返回值、方法名(参数列表){
方法体
}
public void show(){
System.out.println("姓名:" + name + ",年龄:" + age);
}
方法中返回值介绍:
如果方法有返回值,方法中必须使用关键字return返回某个值,返回值类型为该值的类型,且返回值只能有一个。
return的作用:结束方法,返回结果。
注意:当调用有返回值的方法时,需要定义一个变量接受
如果方法没有返回值,返回值类型为void
如何使用java实现类和对象的关系?
- 创建一个类
- 通过这个类创建对象
- 使用对象名调用属性和方法。对象名.属性名,对象名.方法名
方法是一种功能的体现
修饰符public,公共的,公开的,这个方法在哪里都能被调用
返回值类型:
这个方法被调用了, 有没有一个结果给调用者,void没有结果,要结果的话,返回值的具体类型。
当一个方法有返回值的时候,需婴使用return将结果返回。
注意: void 和return只能有1个在方法。
方法名:见名思意, 遵循标识符的命名规则
参数列表:
调用这个方法需不需要有条件,如果需要条件,就在()进行声明,方式和属性声明是一样,此时的参数在方法中是-一个占位符,形式参数,形参在方法中可以直按使用。
方法体:实现功能的具体的代码。
构造方法
作用:创建对象,初始化对象
语法:
//学生类
public class Student {
//属性
String name;
int age;
String sex;
//系统默认的无参构造方法,写和不写他都是存在的
public Student()
}
//有参构造方法,创建对象的时候就已经给了初始值了
public Student (String name,int age,String sex) {
this. name = name;
this. age = age;
this. sex = sex;
}
}
构造方法和普通方法的区别:
构造方法访问修饰符一般是public, 一般方法根据实际情况选择修饰符
构造方法没有返回值类型,一般方法要么无返回值-void,要么有返回值
方法名与类同名,一般方法见名思意,遵循驼峰命名规则
构造方法的方法体是对象的初始化代码,一般方法是功能的实现
调用方式不一致,普通方法需要使用对象来调用,构造方法是new, this, super
方法的重载(overload)
方法重载的判断标准:同类同名不同参,与其他无关。(不同参:不同的参数列表:个数不同,类型不同,顺序不同)
成员变量与局部变量
成员变量是属于类的变量,其实就是类中的属性,类中的每一个方法都可以共享;
成员变量和局部变量区别:
1、定义位置不同
成员变量:定义在类中的变量,属于类
局部变量:定义在方法中的变量,属于方法
2、作用域不同
成员变量:属于类,类中的每一个方法都可以使用
局部变量:属于方法,只能在某一个方法中使用
3、初始值不同
成员变量:有默认的初始值,在加载类的时候,就会给成员变量赋值(默认值)
局部变量:没有初始值,必须初始化之后才可以使用
4、生命周期不同
成员变量:属于类,随着对象的创建而创建,随对象的消失而消失- 垃圾回收器
局部变量:属于方法,随着方法的调用而创建
5、优先级不同
在同一个类中,成员变量和局部变量同名时,局部变量具有更高的优先级
注意:在方法的参数列表中的参数,也是局部变量。
Java的三大特性:封装、继承、和多态
封装
封装的概念
将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问
封装的原则
1、将属性隐藏起来 - 使用private关键字来修饰属性,私有的,私有化的 , 被这个private修饰的内容,只能在本类中使用,可以用来修饰属性和方法
2、对外提供公共的访问方法(赋值,取值), 提供getter,setter 方法来操作隐藏的属性
实现封装的步骤
1、私有化属性;
2、创建公共的getter和setter方法;
3、在setter方法中添加控制语句
private 关键字说明:
被private修饰的属性和方法只能在本类中方法,其他类不能直接访问.
封装的好处
1、隐藏了实现的细节,提高安全性
2、符合java的“高内聚,低耦合”思想
3、提高了软件的独立性和可重用性
包的介绍
作用:
1、文档分门别类,易于查找和管理;
2、解决文件同名冲突问题;
3、有助于实施访问权限管理;
包:package,需要放在java源代码中的第一条语句;以分号结尾。
类似于windows中的文件夹。
包的命名规则:
1、包名由小写字母组成,不能以圆点开头或结尾;
2、包名之前最好加上唯一的前缀,通常是组织倒置的域名;
包的创建方式:
分别创建包和类
创建类的同时创建包
包的导入:
如果需要使用其他包下面的类,可以使用import 关键字导入
导入规则:import 包名.类名
注意:
1、一个类同时引用了两个来自不同包的同名类,必须通过完整类名来区分
2、package和import的顺序是固定的;
package必须位于第一行(忽略注释行);
只允许有一个package语句;
其次是import;
接着是类的声明;
访问权限控制
Java 中一共有四种访问权限控制,其权限控制的大小情况是这样的:public > protected > default(包访问权限) > private
参考以下表格:
- public: 所修饰的类、变量、方法,在任何地方均具有访问权限;
2、protected: 这种权限是为继承而设计的,protected所修饰的成员,对所有子类是可访问的,但只对同包的类是可访问的,对外包的非子类是不可以访问;
3、包访问权限(default): 只对同包的类具有访问的权限,外包的所有类都不能访问;
4、private: 私有的权限,只对本类的方法可以使用;其他地方均不能访问;
static修饰符
static表示“全局”或者“静态”的意思,用来修饰成员变量(属性)和成员方法(方法),也可以形成静态static代码块;
被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类的实例,被类的所有实例对象共享;
static修饰的成员变量和成员方法习惯上称为静态变量和静态方法,static修饰的代码块表示静态代码块。
static代码块
static 代码块,是在类中独立于类成员的 static 语句块,可以有多个,位置可以随便放,它不在任何的方法体内,JVM 加载类时会执行这些静态的代码块,如果 static 代码块有多个,JVM 将按照它们在类中出现的先后顺序依次执行它们,每个静态代码块只会被执行一次。
静态代码块执行的时机:
静态代码块在对象创建之前执行,每创建一个对象都会执行一次构造方法。而每个静态代码块只会被执行一次。第一次创建对象之前
static变量,静态变量
按照是否静态的对类成员变量进行分类可分两种:一种是被static修饰的变量,叫静态变量或类变量;
另一种是没有被static修饰的变量,叫实例变量。实例变量必须通过对象来调用。
静态变量特点:
1、被static修饰的变量静态变量,非静态变量叫实例变量
2、在内存中只有一个,在加载类的时候创建,被所有方法和对象共享
3、其他类中,可以直接通过类名访问(可以通过类名直接调用)
static方法,静态方法
静态方法就是被static修饰的方法,没有被static修饰的方法称为实例方法,实例方法必须要对象才可以调用,
静态方法可以直接通过类名调用,任何的实例也都可以调用
静态方法特点:
1、静态方法中不能使用this和super,this当前对象
2、不能直接访问所属类的实例变量和实例方法 , 面试题:静态方法能不能访问非静态资源?----- 可以的。
3、可直接访问类的静态变量和静态方法,静态能够调用静态资源,不能直接调用非静态资源
4、可直接通过类名.方法名访问
5、规定:静态只能调用静态,非静态只能调用非静态
静态变量和实例变量的比较:
类的成员变量包括:
类变量 (静态变量):
被static修饰的变量
在内存中只有一个拷贝
类内部,可在任何方法内直接访问静
其他类中,可以直接通过类名访问
实例变量:
没有被static修饰的变量
每创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响
必须要通过对象来调用
初始化:
静态变量在创建对象之前会被加载
实例变量,随着对象的创建被创建
注意:在静态资源内部不能直接调用非静态的资源(属性和方法)
规定:静态调用静态,非静态调用非静态。
继承
Java中的继承使用的是extends关键字,继承的类叫做子类(扩展类),被继承的类叫做父类(超类或者基类)。
1、类:类是具有共同属性和行为的一组对象。它是创建对象的模板或蓝图。
2、子类:子类是继承其他类的类。它也称为派生类,扩展类或子类。
3、超类/父类:超类是子类继承功能的类。它也称为基类或父类。-通用的属性和方法
4、可重用性:正如名称所指定的那样,可重用性是一种机制,可以帮助您在创建新类时重用现有类的属性和方法。
5、Java中类只支持单继承,即一个类只能有一个直接父类
子类可以继承父类的那些内容?
1、子类可以继承父类中被public 和protected 修饰的内容。
2、如果子类和父类在同一个包下的话,默认修饰符修饰的内容也会被继承。
子类不能继承哪些内容?
1、私有的内容
2、构造方法是不能被继承的
3、子类和父类不再同一个包下,默认修饰符修饰的内容
java中的类,只能单继承,不能同时继承多个类
可以间接的继承,可以使用父类的父类中的(爷爷)的方法
如何使用继承?
1、编写父类,创建公共的属性和方法
2、编写子类使用extends继承父类
3、编写子类中特有的属性和方法
注意:
1、super关键字代表父类,只能出现在子类的方法和构造方法中
2、在子类构造方法中使用super调用父类构造方法,必须位于第一句;
3、子类不可以直接访问父类中定义为private的属性和方法 - private的东西是不能被继承的。
什么时候使用继承?
符合 is a 关系的设计时,可以考虑使用继承。
例如:小狗是一个宠物,小猫是一个宠物
继承的优点?
将子类共有的属性和方法抽取到父类中,减少重复的代码,实现代码的重用。
方法的重写(overriding)
使用:当父类中的方法不能满足子类的需要。
方法的重写又称方法的覆盖,一般用于子类根据需要可以对父类中的方法进行重新编写
重写的前提是:必须在继承体系下,也就是必须存在继承关系
重载的前提是:同一个类中
方法重写的原则
1、方法名必须相同
2、参数列表必须相同
3、返回值类型相同或者是其子类
4、访问权限相同或不能严于父类
注意:
1、一般不会去改变返回值和访问权限
2、父类的私有方法不能被重写,重写的是可以被继承的方法
3、一般情况下,重写都是会存在一模一样的方法仅仅是方法体不一样。
4、只能重写继承来的方法
方法重写和重载的区别
重载:同类同名不同参,与其他无关(同一个类中,方法名,参数列表不同--个数不同,类型不同,顺序不同)
重写:在子类和父类中存在,同名同参同返回值同访问修饰符的方法(返回值可以是其子类,访问修饰符不能比父类更严格)
object介绍
Object类是所有类的父类;
Object 是类层次结构的根类。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。
Object中常用方法介绍:
类的内容:一般的实体类中都必须包含以下内容:有参构造,无参构造,getset方法,toString() ;
其中比较常用的两种方法为:1、toString,2、equals
多态
什么是多态?
Pet p = new Dog(); // p 就是引用变量
所谓多态,就是指一个引用变量在不同的情况下的多种表现状态。也可以理解为,多态是指通过指向父类的引用变量,来调用在不同子类中实现的方法。
注意:方法重写是实现多态的基础
多态的运用
一般用于继承体系下,子类重写父类的某个方法,调用时根据具体的子类实现去调用子类的方法
抽象方法介绍
被abstract修饰的方法,就是抽象方法。
1.抽象方法和普通的方法有什么区别?
1、语法:抽象方法一定是被abstract修饰的方法, 普通一定不能
2、方法体:抽象方法没有方法体,普通方法一定有
3、位置:抽象方法只能在抽象类中,普通方法随意可以在抽象类中也可以不再抽象类中。
2.抽象类和抽象方法的关系
1、有抽象方法的类,一定是抽象类,但抽象类不一定有抽象方法;
2、一个类继承抽象类,必须重写抽象类中的所有抽象方法,如果没有全部重写,那么子类必须声明为抽象类
3、没有抽象构造方法,也没有抽象静态方法
4、抽象类中可以有构造方法,创建子类的实例时调用
3.抽象类能不能创建对象
不能。为什么?|
他可能存在抽象方法,抽象方法是有缺陷,不完整的方法,如果他能创建对象的话,调用抽象方法的话,没有任何意义
4.抽象类能不能有构造方法?有什么用?
有,任何一个构造方法,第一行都一个super(), 留给子类使用的
注意:不存在抽象的构造方法, 所有的构造方法必须有代码,抽象的方法不能有方法体,没有办法写代码,矛盾!!
5.普通类和抽象类的区别?
1、语法不同,抽象类是被abstract修饰的类,普通类一定不能被abstract修饰;
2、抽象类中可以有抽象方法,普通类一定不能有抽象方法;
3、抽象类不能被实例化,普通类可以去实例化调用;- 创建对象
4、抽象类被继承时,子类必须重写全部的抽象方法,或者将子类声明为抽象类;普通类继承普通类的时候,没有任何限制;
6.抽象类能不能继承普通类?
能,如果一个类没有显示的去继承一个父类,默认的父类是object
7.普通类能不能继承抽象类?
能,注意:子类必须要重写父类中的所有的抽象方法,如果没有全部重写,那么子类必须要声明为一个抽象类
8.什么是抽象类?
被abstract修饰的类,
特点:不能实例化
9.抽象类为什么不能实例化:?
抽象类中可能会有抽象方法,抽象方法是个不完整的方法,有缺陷,没有方法体的 方法,如果能实例化,调用抽象方法。
10.是否存在抽象的静态方法?
不存在,静态方法其实就是一个普通的方法,需要一个方法体。
11.抽象类中是否存在静态方法?
静态方法是独立于对象的,需要实例化,抽象类中是可以存在的,也可以被调用
特征:
1、抽象方法没有方法体,只有方法的声明;
2、如果一个类中存在抽象方法,那么这个类必须声明为抽象类;abstact修饰的类,抽象类不能创建对象
3、抽象类不能被实例化;
4、抽象方法必须在子类中被重写,除非子类也是抽象类;
如:
// 抽象类
public abstract class Pet{
//抽象方法
public abstract void toHospital();
}
向上转型:
把子类对象直接赋给父类引用叫向上转型,向上转型不用强制转换。
//例如:Pet p = new Dog();
注意:
1、此时通过父类引用变量调用的方法是子类重写或继承父类的方法
2、此时通过父类引用变量无法调用子类特有的方法
向下转型:
向下转型需要使用强制类型转换,调用子类特有的方法;
语法:
<子类型> <引用变量名> = (<子类型> )<父类型的引用变量>;
如:
Dog dog=(Dog)pet;//将pet 转换为Dog类型
dog.method();//执行Dog特有的方法
在进行向下转型的时候,非常容易发生类型转换异常
ClassCastException --- 类型转换异常
instanceof用于判断一个引用类型所引用的对象是否是一个类的实例
接口
什么是接口?
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合(接口中的所有的方法都是抽象方法),接口通常以interface来声明。
接口的声明?
语法:
public interface MyInterface {
public abstract void eat(); // 接口中的所有方法都是抽象方法;
void run(); // 可以省略前面的修饰
}
接口的特点?
1、接口中只能编写抽象方法,1.8开始,接口中可以存在普通方法和静态方法,如果需要编写普通方法的话,则必须加default关键字
2、接口中默认的方法就是抽象方法,默认是public abstract 修饰的
3、接口中成员变量必须是常量,默认的修饰符是public static final
4、接口能不能继承接口,可以, 而且接口是可以多继承的
5、抽象类和接口的关系(区别)
class,interface, 成员变量,方法,继承关系,
6、类能不能继承接口,不能继承,- - 个类想拥有接口中的能力,
需要使用implements关键字,实现意思,Cat实现了XXX接口,则必须要实现接口中所有的抽象方法
如果没有全部实现的话嘛,则这个类必须要声明为抽象类
7、一个类能不能在继承另外-一个类的同时去实现-一个接口,可以的
8、接口中有没有构造方法,没有,
9、接口中有没有静态方法,可以的,接口名。方法名
10、接口能不能实例化,不能
如何使用接口?
使用接口的步骤:
1、创建接口,声明方法
2、创建类,实现接口,实现接口中的方法
3、使用实现后的方法执行具体的操作
接口与抽象类的区别 ?
1、抽象类使用关键字abstract class修饰,接口使用关键字interface;
2、抽象类使用关键字extends实现继承,接口使用implements来实现
3、抽象类中可以包含抽象方法和普通方法,接口中只能有抽象方法(1.7);
4、抽象类可以有构造方法,接口中不能有构造方法;
5、抽象类可以有成员变量,接口中只能有常量;
6、抽象类只能单继承,接口可以多继承;
7、抽象类里面的方法可以是public,protect,private,接口的方法只能是public;
异常
什么是异常?
程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常。
常见的异常有:
算术异常:ArithmeticExecption
空指针异常:NullPointerException
数组下标越界异常:ArrayIndexOutOfBoundsException
类型转换异常:ClassCastException
数组负下标异常:NegativeArrayException
字符串转换为数字异常:NumberFormatException
输入类型不匹配:inputMisMatchException
异常处理
什么是异常处理?
异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?
Java提供了更加优秀的解决办法:异常处理机制- 捕获异常,抛出异常。
捕获异常: try , catch , finally
抛出异常:throw, throws
异常的分类
Java标准库内建了一些通用的异常,这些类以Throwable为顶层父类。Throwable又派生出Error类和Exception类。
错误:Error类以及他的子类的实例,代表了JVM本身的错误。错误不能被程序员通过代码处理,Error很少出现。因此,程序员应该关注Exception为父类的分支下的各种异常类。
异常:Exception以及他的子类,代表程序运行时发送的各种不期望发生的事件。可以被Java异常处理机制使用,是异常处理的核心。
Exception这种异常又分为两类:运行时异常和编译异常。
1、运行时异常(不受检异常)
2、编译时异常(受检异常)
捕获异常
捕获异常:一旦方法抛出异常,系统自动根据该异常对象寻找合适异常处理器(Exception Handler)来处理该异常。所谓合适类型的异常处理器指的是异常对象类型和异常处理器类型一致。
try - catch 语句
try {
//可能产生的异常的代码区,也成为监控区
//try块中放可能发生异常的代码。
//如果执行完try且不发生异常,则不会执行catch内的内容,跳过catch,继续向下执行
//如果发生异常,则尝试去匹配catch块。
}catch (SQLException SQLexception) {
//捕获并处理try抛出异常类型为SQLException的异常
//每一个catch块用于捕获并处理一个特定的异常,或者这异常类型的子类。Java7中可以将多个异常声明在一个catch中。
//catch后面的括号定义了异常类型和异常参数。如果异常与之匹配且是最先匹配到的,则虚拟机将使用这个catch块来处理异常,执行catch块里面的代码。
//在catch块中可以使用这个块的异常参数来获取异常的相关信息。异常参数是这个catch块中的局部变量,其它块不能访问。
//如果try中没有发生异常,则所有的catch块将被忽略。继续向下执行
//如果try有异常,当发生异常后,try中异常后面的代码不会被执行。
//如果catch中的异常与之匹配,则会执行catch代码块,并且继续向下执行
//如果catch中没有与报错信息匹配的异常,此时程序报错,程序停止
}catch(Exception e) {
//捕获并处理try抛出异常类型为ExceptionType2的异常
}
try-catch代码块的执行顺序:
A)try没有异常时,try代码块中的语句依次被执行,跳过catch。执行后续代码。
B)try捕获到异常时,如果存在与之匹配的catch,则跳到该catch代码块执行处理;处理之后继续执行后续代码。
注意,try代码块出现异常之后的代码不会被执行。
C)try捕获到异常时,如果没有与之匹配的catch子句,则该异常交给JVM处理;如果存在finally,则其中的代码仍然被执行,但是try块发生异常之后的代码和finally之后的代码不会被执行。
补充:
在catch块中对异常的处理,我们可以使用自定义的输出语句进行提示,也可以使用异常类为我们提供的方法
printStackTrace() 输出异常的堆栈信息 -- 在命令行打印异常信息在程序中出错的位置及原因
try-catch-finally 语句
可以在try - catch 后面加上finally 语句块;
Finally 表示最终的意思,不管是否发生异常,都会被执行。
try {
//可能产生的异常的代码区
}catch (ExceptionType1 e) {
//捕获并处理try抛出异常类型为ExceptionType1的异常
}catch (ExceptionType2 e){
//捕获并处理try抛出异常类型为ExceptionType2的异常
}finally{
//finally块通常是可选的。
//无论异常是否发生,异常是否匹配被处理,finally都会执行。
//一个try至少要有一个catch块,否则, 至少要有1个finally块。但是finally不是用来处理异常的,finally不会捕获异常。
//finally主要做一些清理工作,如流的关闭,数据库连接的关闭等。
}
try-catch-finally代码块的执行顺序:
- try没有捕获异常时,try代码块中的语句依次被执行,跳过catch。如果存在finally则先执行finally在执行后续代码,否则执行后续代码。
- try捕获到异常时,如果存在匹配的catch,则跳到该catch代码块执行处理。如果存在finally则先执行finally代码块,然后执行后续代码;否则直接执行后续代码。
另外注意,try代码块出现异常之后的代码不会被执行。
- try捕获到异常时,如果没有匹配的catch,则该异常交给JVM处理。如果存在finally,则其中的代码仍然被执行,但是finally之后的代码不会被执行。
注意:
- Finally唯一不被执行的情况:当发生异常时,在程序中手动的退出系统:System.exit(1);
- 当try 或者 catch 块中存在return的时候,同时存在finally时,其执行顺序是怎样的?
如果try代码块或者catch代码块中有return语句时,finally代码块将在方法返回前被执行。先执行finally , 最后执行return
捕获总结
try代码块:用于捕获异常。其后可以接零个或者多个catch块。如果没有catch块,后必须跟finally块,来完成资源释放等操作;
catch代码块:用于捕获异常,并在处理异常。
finally代码块:无论是否捕获异常,finally代码总会被执行。如果try代码块或者catch代码块中有return语句时,finally代码块将在方法返回前被执行。
唯一一种finally不会被执行的情况就是,发送异常时,手动的退出了系统。
抛出异常
如果一个方法可能会出现异常,但没有能力处理这种异常,或者自己不想解决的话,可以使用甩锅的方式解决。
throws抛出异常
如果一个方法可能抛出异常,但是没有能力处理该异常或者需要通过该异常向上层汇报处理结果,可以在方法声明时使用throws来抛出异常。这就相当于计算机硬件发生损坏,但是计算机本身无法处理,就将该异常交给维修人员来处理。
Public void methodName() throws Exception1,Exception2….{
}
其中Exception1,Exception2…为异常列表,一旦该方法中某行代码抛出异常,则该异常将由调用该方法的上层方法处理。如果上层方法无法处理,可以继续将该异常向上层抛。
如果一个方法向外抛出了异常,那异常由谁来解决?
1、调用者,谁调用这个方法就由谁来解决。
2、如果调用者也解决不了呢?调用者可以继续向外抛出这个异常。
throw抛出异常
在方法内,用throw来抛出一个Throwable类型的异常。一旦遇到到throw语句,后面的代码将不被执行。然后,便是进行异常处理——包含该异常的try-catch最终处理,也可以向上层抛出。注意我们只能抛出Throwable类和其子类的对象。
throw new ExceptionType;
比如我们可以抛出:throw new Exception(); 当在方法内部抛出一个异常时,一般也会在方法上再次抛一个异常。
也有时候我们也需要在catch中抛出异常,这也是允许的,比如说:
Try{
//可能会发生异常的代码
}catch(Exceptione){
throw new Exception(e);
}
throw与throws
自定义异常
如果 Java 提供的内置异常类型不能满足程序设计的需求,可以设计自己的异常类型,
自定义异常类必须继承现有的 Exception 类或 Exception 的子类来创建,其语法形式为
class <自定义异常名> extends <Exception>
在编码规范上,一般将自定义异常类的类名命名为 XXXException,其中 XXX 用来代表该异常的作用
自定义异常类一般包含两个构造方法:一个是无参的默认构造方法,另一个构造方法以字符串的形式接收一个异常消息,并将该消息传递给父类的构造方法。
自定义异常的具体步骤:
1:定义一个类继承Exception或者其子类;
2:编写构造方法(无参和有参);
3:在需要的地方调用异常类(使用throw 抛出实例化后的异常)- 在方法的声明中需要声明
异常使用原则
从性能角度看:
1:不要将所有的代码都放在try中,try只放有可能发送异常的代码;
2:在catch中指定具体的异常类型。
记住:能解决的使用捕获,不能解决的使用抛出
总结:
以上就是今天要讲的内容,本文仅仅简单介绍了面向对象的一些理论知识,而面向对象还是需要亲自去练,多练多试才能更加理解其中的原理。