第7章 内部类与异常类

主要内容

基本内容:
 内部类
 匿名类
 异常类
 断言
§7.1 内部类
Java支持在一个类中声明另一个类,这样的类称作内部类,而包含内部类的类成为内部类的外嵌类。
例如:某种类型的农场饲养了一种特殊种类的牛,但不希望其他农场饲养这种特殊种类的牛,那么这种类型的农场就可以将创建这种特殊种牛的类作为自己的内部类。
下面的例子1(Example7_1.java)中有一个RedCowForm(红牛农场)类,该类中有一个名字为RedCow(红牛)的内部类。程序运行效果如图7.1。
例子1
RedCowForm.java

public class RedCowForm {
static String formName;
RedCow cow; //内部类声明对象
RedCowForm() {
}
RedCowForm(String s) {
cow = new RedCow(150,112,5000);
formName = s;
}
public void showCowMess() {
cow.speak();
}
class RedCow { //内部类的声明
String cowName = “红牛”;
int height,weight,price;
RedCow(int h,int w,int p){
height = h;
weight = w;
price = p;
}
void speak() {
System.out.println(“偶是”+cowName+",身高:"+height+“cm 体重:”+
weight+“kg,生活在”+formName);
}
} //内部类结束
} //外嵌类结束

Example7_1.java

public class Example7_1 {
public static void main(String args[]) {
RedCowForm form = new RedCowForm(“红牛农场”);
form.showCowMess();
form.cow.speak();
}
}

§7.2 匿名类
Java允许我们直接使用一个类的子类的类体创建一个子类对象。
7.2.1和子类有关的匿名类
创建子类对象时,除了使用父类的构造方法外还有类体,此类体被认为是一个子类去掉类声明后的类体,称作匿名类。
假设Bank是类,那么下列代码就是用Bank的一个子类(匿名类)创建对象:
new Bank () {
匿名类的类体
};
例子2
OutputAlphabet.java

abstract class OutputAlphabet {
public abstract void output();
}

OutputEnglish.java

public class OutputEnglish extends OutputAlphabet { //输出英文字母的子类
public void output() {
for(char c=‘a’;c<=‘z’;c++) {
System.out.printf("%3c",c);
}
}
}

ShowBoard.java

public class ShowBoard {
void showMess(OutputAlphabet show) { //参数show是OutputAlphabet类型的对象
show.output();
}
}

Example7_2.java

public class Example7_2 {
public static void main(String args[]) {
ShowBoard board = new ShowBoard();
board.showMess(new OutputEnglish());//向参数传递OutputAlphabet的子类 //OutputEnglish的对象
board.showMess(new OutputAlphabet()//向参数传递OutputAlphabet的匿名子 //类的对象
{ public void output()
{ for(char c=‘α’;c<=‘ω’;c++) //输出希腊字母
System.out.printf("%3c",c);
}
}
); //请注意分号在这里
}
}

7.2.2 和接口有关的匿名类
假设Computable是一个接口,那么,Java允许直接用接口名和一个类体创建一个匿名对象,此类体被认为是实现了Computable接口的类去掉类声明后的类体,称作匿名类。
下列代码就是用实现了Computable接口的类(匿名类)创建对象:
new Computable() {
实现接口的匿名类的类体
} ;
例子3
Example7_3.java

interface SpeakHello {
void speak();
}
class HelloMachine {
public void turnOn(SpeakHello hello) {
hello.speak();
}
}
public class Example7_3 {
public static void main(String args[]) {
HelloMachine machine = new HelloMachine();
machine.turnOn( new SpeakHello() { //和接口SpeakHello有关的匿名类
public void speak() {
System.out.println(“hello,you are welcome!”);
}
}
);
machine.turnOn( new SpeakHello() { //和接口SpeakHello有关的匿名类
public void speak() {
System.out.println(“你好,欢迎光临!”);
}
}
);
}
}

§7.3 异常类
所谓异常就是程序运行时可能出现一些错误,比如试图打开一个根本不存在的文件等,异常处理将会改变程序的控制流程,让程序有机会对错误作出处理。程序运行出现异常时,Java运行环境就用异常类Exception的相应子类创建一个异常对象,并等待处理。
异常对象可以调用如下方法得到或输出有关异常的信息:
public String getMessage();
public void printStackTrace();
public String toString();
§7.3.1 try~catch语句
Java使用trycatch语句来处理异常,将可能出现的异常操作放在trycatch语句的try部分,将发生异常后的处理放在catch部分。
try~catch语句的格式如下:
try {
包含可能发生异常的语句
}
catch(ExceptionSubClass1 e) {

}
catch(ExceptionSubClass2 e) {

}
带finally子语句的try~catch语句,语法格式如下:
try{}
catch(ExceptionSubClass e){ }
finally{}
其执行机制是在执行try~catch语句后,执行finally子语句,也就是说,无论在try部分是否发生过异常,finally子语句都会被执行。
例子4
Example7_4.java

public class Example7_4 {
public static void main(String args[ ]) {
int n = 0,m = 0,t = 1000;
try{ m = Integer.parseInt(“8888”);
n = Integer.parseInt(“ab89”); //发生异常,转向catch
t = 7777; //t没有机会被赋值
}
catch(NumberFormatException e) {
System.out.println(“发生异常:”+e.getMessage());
}
System.out.println(“n=”+n+",m="+m+",t="+t);
try{ System.out.println(“故意抛出I/O异常!”);
throw new java.io.IOException(“我是故意的”); //故意抛出异常
//System.out.println(“这个输出语句肯定没有机会执行,必须注释,否则编译 出错”);
}
catch(java.io.IOException e) {
System.out.println(“发生异常:”+e.getMessage());
}
}
}

§7.3.2 异常的声明
一个方法不处理它产生的异常,而是沿着调用层次向上传递,由调用它的方法来处理这些异常,叫声明异常.
声明异常的方法:在产生异常的方法名后面加上要抛出(throws)的异常的列表:
如:void compute(int x) throws ArithmeticException
{//这里有异常发生,但是并没有处理…}
例子5
BankException.java

public class BankException extends Exception {
String message;
public BankException(int m,int n) {
message = “入账资金”+m+“是负数或支出”+n+“是正数,不符合系统要求.”;
}
public String warnMess() {
return message;
}
}

Bank.java

public class Bank {
private int money;
public void income(int in,int out) throws BankException {
if(in<=0||out>=0||in+out<=0) {
throw new BankException(in,out); //方法抛出异常,导致方法结束
}
int netIncome = in+out;
System.out.printf(“本次计算出的纯收入是:%d元\n”,netIncome);
money = money+netIncome;
}
public int getMoney() {
return money;
}
}

Example7_5.java

public class Example7_5 {
public static void main(String args[]) {
Bank bank = new Bank();
try{ bank.income(200,-100);
bank.income(300,-100);
bank.income(400,-100);
System.out.printf(“银行目前有%d元\n”,bank.getMoney());
bank.income(200, 100);
bank.income(99999,-100);
}
catch(BankException e) {
System.out.println(“计算收益的过程出现如下问题:”);
System.out.println(e.warnMess());
}
System.out.printf(“银行目前有%d元\n”,bank.getMoney());
}
}
§7.4 断言
断言语句用于调试代码阶段。在调试代码阶段让断言语句发挥作用,这样就可以发现一些致命的错误,当程序正式运行时就可以关闭断言语句,但仍把断言语句保留在源代码中,如果以后应用程又需要调试,可以重新启用断言语句。
使用关键字assert声明一条断言语句,断言语句有以下两种格式:
assert booleanExpression;
assert booleanExpression:messageException;
例子6
Example7_6.java

import java.util.Scanner;
public class Example7_6 {
public static void main (String args[ ]) {
int [] score = {-120,98,89,120,99};
int sum = 0;
for(int number:score) {
assert number>=0:“负数不能是成绩”;
sum = sum+number;
}
System.out.println(“总成绩:”+sum);
}
}
总结
Java支持在一个类中声明另一个类,这样的类称作内部类,而包含内部类的类成为内部类的外嵌类。
和某类有关的匿名类就是该类的一个子类,该子类没有明显的用类声明来定义,所以称做匿名类。
和某接口有关的匿名类就是实现该接口的一个类,该子类没有明显的用类声明来定义,所以称做匿名类。
Java使用trycatch语句来处理异常,将可能出现的异常操作放在trycatch语句的try部分,当try部分中的某个方法调用发生异常后,try部分将立刻结束执行,而转向执行相应的catch部分。

你可能感兴趣的:(第7章 内部类与异常类)