6.1 接口
注:
- 接口的访问控制符和类的一样。或为public或为缺省。
- public接口可以被任何一个类使用,友好接口可以被同一个包中的类使用。
- 接口中的属性都是用final修饰的常量,其默认修饰符为public。
- 接口中的方法都是用abstract修饰的抽象方法,在接口中只能给出这些抽象方法的方法名、返回值类型和参数列表,而不能定义方法体。
- 接口只关心功能,并不关心功能的具体实现。
- 使用相同接口的类不一定有继承关系。
例1
interface 收费
{ public void 收取费用();}
interface 调节温度
{ public void controlTemperature();}
class 公共汽车 implements 收费
{ public void 收取费用() { System.out.println("公共汽车:一元/张,不计算公里数");}
}
class 出租车 implements 收费, 调节温度
{ public void 收取费用() { System.out.println("出租车:1.60元/公里,起价3公里");}public void controlTemperature(){ System.out.println("安装了Hair空调");}
}
class Example4_19
{ public static void main(String args[]){ 公共汽车 七路=new 公共汽车();出租车 天宇=new 出租车();七路.收取费用();天宇.收取费用();天宇.controlTemperature(); }}
三、接口的实现
一个类要实现某个或某几个接口时,有如下注意事项:
- 在类的声明部分,用implements关键字声明该类将要实现哪些接口;
- 一个类在实现某接口的抽象方法时,必须使用完全相同的方法头。
- 接口的抽象方法,其访问控制符都已指定(或默认)是public,所以类在实现方法时,必须显式地使用public修饰符,否则将被系统警告:缩小了接口中定义的方法的访问控制范围。
例2:
interface ShowMessage
{ void 显示商标(String s);}
class TV implements ShowMessage
{ public void 显示商标(String s) { System.out.println(s); }
}
class PC implements ShowMessage
{ public void 显示商标(String s) { System.out.println(s); }
}
public class Example4_20
{ public static void main(String args[]){ ShowMessage sm; sm=new TV( ); sm.显示商标("长城牌电视机"); sm=new PC( ); sm.显示商标("联想奔月5008PC机"); }
}
四、接口回调
接口回调是指:可以把实现某一接口的类创建的对象的引用赋给该接口变量,那么该接口变量就可以调用被类实现的接口中的方法。实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口中的方法。
例3:
interface CanFight
{ void fight(); }
interface CanSwim
{ void swim(); }
interface CanFly
{ void fly(); }
class ActionCharacter
{ public void fight(){ System.out.println("class::ActionCharacter:fight"); }
}
class Hero extends ActionCharacter implements CanFight, CanSwim, CanFly
{ public void swim(){System.out.println("Swim");}public void fly() {System.out.println("fly");}}public class Adventure
{ static void t(CanFight x) { x.fight(); }public static void main(String[] args) { Hero h = new Hero();t(h); h.swim();h.fly();}}
6.2 异常
一、异常机制
概念
异常是指当程序出现错误后,程序如何处理。具体来说,异常机制提供了程序退出的安全通道。当出现错误后,程序执行的流程发生改变,程序的控制权转移到异常处理器。
二、异常处理流程
class DivZeroExcep
{public static void main(String args[]) {int a=3,b=0,c;try{ c=a/b;System.out.println("c="+c);}catch(Exception e){System.out.println("divide abnormal.");}}
}
三、异常的类型
- 在“异常”层次的最上层有一个单独的类叫做Throwable。这个类用来表示所有的异常情况。每个异常类型都是Throwable的子类。
- 一类是Error,它定义了那些通常无法捕捉到的“异常”。应用程序不应该抛出这种类型的对象(一般是由虚拟机抛出)。如果出现这种错误,除了尽力使程序安全退出外,在其他方面是无能为力的。所以,在进行程序设计时,应该更关注Exception体系。
- 另一类是Exception,是用户程序能够捕捉到的异常情况。我们可通过产生它的子类来创建自己的异常。
- 处理RuntimeException的原则是:如果出现RuntimeException,那么一定是程序员的错误。例如,可以通过检查数组下标和数组边界来避免数组越界访问异常。
- 其他(IOException等等)异常一般是外部错误,例如试图从文件尾后读取数据等,这并不是程序本身的错误,而是在应用环境中出现的外部错误。
1.未经检查的异常(unchecked exception)
2.受检查的异常(checked exception)
class DivZeroExcep
{public static void main(String args[]) {int a=3,b=2,c;int k[]=new int[10];try{c=a/b;k[10]=100;System.out.println("c="+c+" k[10]="+k[10]);}catch(ArithmeticException e){System.out.println("divide abnormal");}catch(ArrayIndexOutOfBoundsException e){System.out.println("Array Index out of bound.");}}
}
某些情况,由单个代码段可能引起多个异常。处理这种情况,可以定义两个或更多的catch子句,每个子句捕获一种类型的异常。当异常被引发时,每一个catch子句被依次检查,第一个匹配异常类型的子句执行。当一个catch语句执行后,其他的子句被旁路,执行从 try/ catch块以后的代码开始继续。
注:
当用多个catch语句时,需要记住异常子类必须在它们任何父类之前使用。因为运用父类的catch语句将捕获该类型及其所有子类类型的异常。这样,如果子类在父类后面,子类将永远不会被执行。Java中永远也不能被执行的代码是一个错误。
四、异常抛出
class MmExcep
{public static void main(String args[]) {int b=0;try{if(b==0) throw new ArithmeticException();}catch(ArithmeticException e){System.out.println("divide abnormal");}}
}
2. throws语句
例1:
class myException extends Exception
{public myException(String msg){super(msg);}
}
class Show
{ void show(int x) throws myException{ if (x<0){throw new myException("不能传小于0的参数"); }System.out.println("hello,world.");}
}
class p4_16
{public static void main(String[] args) { Show k=new Show();try{k.show(3);k.show(-1);}catch (myException f){System.out.println(f.getMessage());} }
}
上机实践4-实验3 接口回调
Road.java
interface ComputerWeight
{public double computeWeight();
}
class Television implements ComputerWeight
{ 【代码1】 //实现computeWeight()方法。
}
class Computer implements ComputerWeight
{ 【代码2】 //实现computeWeight()方法。
}
class WashMachine implements ComputerWeight
{ 【代码3】 //实现computeWeight()方法。
}
class Car
{ ComputerWeight[] goods;double totalWeights=0;Car(ComputerWeight[] goods){this.goods=goods;}public double getTotalWeights(){totalWeights=0;【代码4】 //计算totalWeightsreturn totalWeights;}
}
public class Road
{public static void main(String args[]){ ComputerWeight[] goodsOne=new ComputerWeight[50],goodsTwo=new ComputerWeight[22] ; for(int i=0;i<goodsOne.length;i++){ if(i%3==0)goodsOne[i]=new Television();else if(i%3==1)goodsOne[i]=new Computer();else if(i%3==2)goodsOne[i]=new WashMachine();} for(int i=0;i<goodsTwo.length;i++){ if(i%3==0)goodsTwo[i]=new Television();else if(i%3==1)goodsTwo[i]=new Computer();else if(i%3==2)goodsTwo[i]=new WashMachine();} Car 大货车=new Car(goodsOne);System.out.println("大货车装载的货物重量:"+大货车.getTotalWeights());Car 小货车=new Car(goodsTwo);System.out.println("小货车装载的货物重量:"+小货车.getTotalWeights());}
}
实验后练习:
- 请在实验的基础上再编写一个实现ComputerWeight接口的类,比如Refrigerrator。这样一来,大货车或小货车装载的货物中就可以有Refrigerrator类型的对象。
- 增加一个实现ComputerWeight接口的类后,Car类需要进行修改吗?