------- android培训、java培训、期待与您交流! ----------
Java面向对象4
一:内部类
1.内部类概述:将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)。
2.访问特点:
内部类可以直接访问外部类中的成员,包括私有成员。
而外部类要访问内部类中的成员必须要建立内部类的对象。
3.内部类的位置:
(1).成员位置-成员内部类
(2).局部位置-局部内部类
4.成员内部类:
(1).如果想在测试类中,直接使用内部类。那么请按照如下格式:
外部类名.内部类名 变量 = 外部类对象.内部类对象;
(2).如果内部类是static修饰
格式:外部类名.内部类名 变量 = new 外部类名.内部类名();
5,内部类的修饰符:
(1).private 为了安全考虑。常见用法。
(2).static 为了方便。常见用法。
6.结论:局部内部类访问局部变量,该变量必须被final修饰。
为什么?
局部变量会在方法调用完毕后,立马消失。
而局部内部类中如果有地方使用着局部变量,当方法消失后,
这个方法区中的内容还没有消失,也就是说这个变量还必须存在。
所以,为了延长局部变量的生命周期,就加final修饰了。
7.匿名内部类:没有名字的局部内部类。
格式:
new 类名或者接口名() {
重写类或者接口中的方法。
也可以自己定义新的方法。
};
8.前提:必须存在一个类,抽象类,或者接口。
理解:是一个继承了类或者实现了接口的匿名的子类对象。
9.什么时候使用匿名内部类呢?
一般来说,当接口或者抽象类中的方法在3个以下的时候。考虑使用匿名内部类。
以后在你看到一个方法接收的形式参数是一个抽象类或者接口的时候。
就可以考虑采用匿名内部类实现。
二:包
1.包
(1).包其实就是文件夹。用于区分相同的类名。
(2).格式:package 包名1.包名2...;
(3).带包的编译和运行
A.手动建包
B.自动建包
2.导包
(1).一般来说,用一个类,需要用该类的全路径名称。
如果多个地方使用,就比较麻烦,所以java提供了导包操作。
(2).格式:import 包名1.包名2...类名;
下面这种属于把指定包下的类都导入。这种用法不推荐。我们应该用谁导谁。
import 包名1.包名2...*;
(3).package,import,class的顺序
package -- import -- class
3.四种权限修饰符
本类 同包(无关类或者子类) 不同包(子类) 不同包(无关类)
private Y
默认 Y Y
protected Y Y Y
public Y Y Y Y
推荐:
成员变量 private
构造方法 public
成员方法 public
4.不同修饰符修饰的内容
类 成员变量 成员方法 构造方法
private Y Y Y
默认 Y Y Y Y
protected Y Y Y
public Y Y Y Y
abstract Y Y
static Y Y
final Y Y Y
5.注意,常见规则如下:
(1).以后,所有的类都用public修饰。并且,在一个java文件中,只写一个类。
(2).以后,所有的成员变量用private修饰。
(3).以后,所有的成员方法用public修饰。
(4).如果是抽象类或者接口:public abstract + ...
(5).以后,所有的构造方法用public修饰。
(6).如果类是工具类或者单例类:构造用private修饰
三:异常
1.思想:我们在编写程序的时候,可能会有很多的问题存在。为了将来方便的表示这些的问题的原因,类型,位置。java就提供了异常对象供我们使用。
2.异常:程序出现了不正常的情况。
3.举例:
电脑键盘不灵了。
原因:敲快了,进水了,线路坏了。
解决方案:
(1).敲快了 -- 慢点敲
(2).进水了 -- 把水干净
(3).线路坏了 -- 去中关村休,买个新的。
4.对应着异常:
Throwable
Error:严重 问题,通常出现重大问题如:运行的类不存在或者内存溢出等。是不需要处理的。一般这种情况是需要修改代码的。
Exception:不严重
编译期间:这个是我们需要处理的。
运行期间:这个是我们不需要处理,这个是需要修改的代码。
5.出现问题
(1).如果出现了问题,我们自己没有处理,jvm会采用自动的处理方式?
它就把异常的类型,原因,位置直接显示在了控制台。后面的代码是不能执行的。
(2).如果程序有异常,怎么解决呢?
A.编写处理代码
基本格式:
try {
可能发生问题的代码。
} catch(异常类名 变量名) {
异常处理代码。
}
B.抛出
代码体现
public class ExceptionDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入被除数:");
int a = sc.nextInt();
System.out.println("请输入除数:");
int b = sc.nextInt();
try {
int c = a / b;
System.out.println(c);
} catch (ArithmeticException ae) {
// 继续操作
// 返回一个错误页面
System.out.println("除数不能为0");
}
System.out.println("新年快乐");
}
}
6.一个代码中,有多个问题,怎么解决呢?
(1).一个个用异常处理方案解决。
(2).针对所有问题,写一个try...catch代码。
try{}catch(){}catch(){}...
(3).注意:在异常处理中,一旦try里面有问题了。就直接跳到catch里面执行。
代码体现:
public class ExceptionDemo2 {
public static void main(String[] args) {
// method1();
method2();
}
public static void method2() {
try {
// ArithmeticException
int a = 10;
// int b = 0;
int b = 2;
System.out.println(a / b);
// ArrayIndexOutOfBoundsException
int[] arr = { 1, 2, 3 };
System.out.println(arr[3]);
// 继续操作
System.out.println("over");
} catch (ArithmeticException ae) {
System.out.println("除数不能为0");
} catch (ArrayIndexOutOfBoundsException ae) {
System.out.println("数组越界异常");
}
}
// 针对每一个异常写一个try...catch代码。
public static void method1() {
// ArithmeticException
int a = 10;
int b = 0;
try {
System.out.println(a / b);
System.out.println("hello");
} catch (ArithmeticException ae) {
System.out.println("除数不能为0");
}
// ArrayIndexOutOfBoundsException
int[] arr = { 1, 2, 3 };
try {
System.out.println(arr[3]);
} catch (ArrayIndexOutOfBoundsException ae) {
System.out.println("数组越界异常");
}
// 继续操作
System.out.println("over");
}
}
7.注意:异常或者错误,都是以他们所在体系的父亲作为后缀。
XxxException
XxxError
针对多个异常,写一个try的代码,catch里面会不会有顺序问题呢?
如果异常是平级关系,没有顺序问题。
如果异常存在着子父关系,父一定要放在最后。
8.JDK7新特性:多个catch用一个catch替代。 不是说多个catch的内容,用一个Exception处理。
格式:catch(异常1 | 异常2 | 异常3 ... 变量名){}
9.基本格式:
try {
可能有问题的代码
} catch(异常类名 变量名) {
处理方案。变量名.printStackTrace();
} finally {
释放资源。(数据库,IO)
}
finally:里面代码永远会执行。
代码体现:
public class FinallyDemo {
public static void main(String[] args) {
int a = 10;
int b = 0;
try {
System.out.println(a / b);
} catch (ArithmeticException ae) {
ae.printStackTrace();
} finally {
System.out.println("over");
}
}
}
10.常见面试题
(1).finally里面的代码真的永远会执行吗?
会永远执行。但是有一个特殊情况:在代码执行到finally之前,jvm就退出了。
(2).加入在catch里面有return语句,请问finally里面的代码还会执行吗?如果执行,是在return前,还是return后?
会执行。在return之间执行。
11.把异常抛出,方法调用中常见。
怎么抛出呢?
格式:在方法名称后面跟一个关键字:throws 异常类名
12.异常的分类:
(1).Exception下非RuntimeException 编译时异常
(2).RuntimeException 运行时异常
13.异常处理:
(1).try...catch...finally
(2).throws
请问选择谁?
如果能够处理,尽量选择(1)。否则选择(2)。
14.运行时期异常和编译时期异常的区别?
(1).运行时期异常
是不需要try...catch或者throws的。
(2).编译时期异常
编译时期异常是需要进行处理的。
15.java虽然已经考虑到了很多种异常情况,但是,有些需求java程序是考虑不到的。比如说:我要求学生的分数不能为负数。
那么,针对这种情况,我们就要编写自定义异常类进行处理。
如何编写一个自定义异常类呢?
就是自定义一个类,去继承Exception或者RuntimeException。
开发中:一般继承自RuntimeException。
一旦判断需要做某些异常处理的时候,就应该在方法内部用throw关键字把该异常对象抛出。
格式:
方法内部
throw 异常对象;
四:总结
1.内部类
(1).把类定义在一个类的内部。
(2).访问特点:
A.内部类可以直接访问外部类成员,包括私有。
B.外部类要想访问内部类成员,必须创建对象。
(3).内部类分类:
A.成员位置
private 安全
static 方便调用
B.局部位置
定义在方法中。
局部内部类访问局部变量必须加final修饰。
延迟生命周期。
(4).匿名内部类
A.是定义在局部位置的没有名字的内部类。
B.前提:存在一个类,抽象类,或者接口。
C.格式:
new 类或者接口名() {
重写方法;
}
本质理解:其实这是一个继承类或者实现接口的匿名的子类对象。
D.使用:
当看到方法的形式参数是接口或者抽象类的时候。
用匿名内部类改进。(集合,IO,awt)
2.异常
(1).异常:就是程序出现的不正常情况。
(2).异常体系:
A.Throwable
|--Error 严重的问题,是处理不了的。要改正代码的。
|--Exception 非RuntimeException的,是需要处理的。编译期异常。
|--RuntimeException 不需要处理的,是需要改代码的。运行期异常。
B.举例:
Error:
地震,海啸。
Exception:
感冒了,头疼。
C.注意:
每种体系的子类都是以父亲的名称作为后缀。
XxxError
XxxException
(3).java虚拟机的默认处理方式
把异常的类名,原因,位置等信息显示在控制台。
一旦有异常发生,其后的代码不能继续执行。
(4).异常的解决方案:
A.自己处理
基本格式:
try {
可能发生异常的代码;
} catch(异常类名 变量名) {
异常的处理代码;
} finally {
释放资源的代码;
}
注意:一旦有一次发生,就会立马执行catch里面的代码。
变形格式:
try...catch
try...catch...catch
try...catch...catch...finally
try...finally
JDK7针对多个catch进行了优化:catch(异常1 | 异常2 | 异常3 ... 变量){}
注意:这些异常必须是平级关系。
和try...catch...catch的不同点是JDK7的这种方案是必须平级关系,不能有子父关系。
而try...catch...catch父亲放最后是可以的。
B.抛出处理:用throws关键字在方法上声明(抛出)。
C.到底使用谁?
a.能自己处理的尽量自己处理。
b.实在不行,先抛了在说。
(5).finally的特点及面试题
A.特点
里面的代码永远会执行。除非前面退出jvm。
B.面试题
a.final,finally,finalize的区别?
b.finally里面的代码永远会执行吗?
c.假如在catch里面有ruturn,finally里面的代码还能被执行吗?
如果能,请问是在return前,还是在return后?
(6).Exception和RuntimeException的区别?
A.Exception 编译时期异常,必须处理的。
如果在方法上,throws了该类型的异常,将来调用者必须处理。
如果在方法内部,throw了该类型的异常,必须在方法上throws该异常。
B.RuntimeException 运行时期异常,是不需要处理的。要改代码的。
如果在方法上,throws了该类型的异常,不需要处理。
如果在方法内部,throw了该类型的异常,方法上可以throws该异常,也可以不throws该异常。
(7).throw和throws的用法和区别?
A.throw
用法:用在方法内部,后面跟的是异常对象名称。
区别:用throw抛出了编译时期异常,方法上面必须用throws抛出。
用throw抛出了运行时期异常,方法上面可以不用throws抛出。
B.throws
用法:用在方法声明上,后面跟的是异常类名。
区别:用throws在方法上声明了异常,内部可以没有throw