接口与多态教案.docx
《接口与多态教案.docx》由会员分享,可在线阅读,更多相关《接口与多态教案.docx(35页珍藏版)》请在冰豆网上搜索。
接口与多态教案
第5章接口与多态教案
1.教学内容
●接口作用及语法
●塑型的概念及应用
●多态的概念及引用
●构造方法的调用顺序及其中的多态方法
2.教学要求
●理解接口、塑型、多态的概念并能熟练应用
●熟练掌握构造方法的调用顺序,理解编写时需要注意的问题
●自学内部类的语法结构及其应用场合
3.授课时间:
4学时
4.授课方式:
讲授+案例讲解与演示
5.课堂组织:
(1)每次课用5分钟时间回顾上次讲课内容
(2)每次课用5分钟时间总结本次课内容
(3)在讲课过程中注意案例分析,调动学生积极性
6.授课内容:
5.1接口
●接口
●与抽象类一样都是定义多个类的共同属性
●使抽象的概念更深入了一层,是一个“纯”抽象类,它只提供一种形式,并不提供实现
●允许创建者规定方法的基本形式:
方法名、参数列表以及返回类型,但不规定方法主体
●也可以包含基本数据类型的数据成员,但它们都默认为static和final
5.1.1接口的作用及语法
接口
●接口的作用
●是面向对象的一个重要机制
●实现多继承,同时免除C++中的多继承那样的复杂性
●建立类和类之间的“协议”
●把类根据其实现的功能来分别代表,而不必顾虑它所在的类继承层次;这样可以最大限度地利用动态绑定,隐藏实现细节
●实现不同类之间的常量共享
5.1.1接口的作用及语法
——与抽象类的不同
接口
●接口允许我们在看起来不相干的对象之间定义共同行为
5.1.1接口的作用及语法
——例5_1
接口
●保险公司的例子
●具有车辆保险、人员保险、公司保险等多种保险业务,在对外提供服务方面具有相似性,如都需要计算保险费(premium)等,因此可声明一个Insurable接口
●在UML图中,实现接口用带有空三角形的虚线表示
5.1.1接口的作用及语法
接口
●接口的语法
●声明格式为
●[接口修饰符]interface接口名称[extends父接口名]{
●…//方法的原型声明或静态常量
●}
●接口的数据成员一定要赋初值,且此值将不能再更改,允许省略final关键字
●接口中的方法必须是“抽象方法”,不能有方法体,允许省略public及abstract关键字
5.1.1接口的作用及语法
——例5_1保险接口的声明
接口
●例5.1中的Insurable接口声明如下,可见其中的方法都是抽象方法
●publicinterfaceInsurable{
●publicintgetNumber();
●publicintgetCoverageAmount();
●publicdoublecalculatePremium();
●publicDategetExpiryDate();
●}
5.1.1接口的作用及语法
——例5_2
接口
●声明一个接口Shape2D,可利用它来实现二维的几何形状类Circle和Rectangle
●把计算面积的方法声明在接口里
●pi值是常量,把它声明在接口的数据成员里
●interfaceShape2D{ //声明Shape2D接口
●finaldoublepi=3.14; //数据成员一定要初始化
●publicabstractdoublearea(); //抽象方法
●}
●在接口的声明中,允许省略一些关键字,也可声明如下
●interfaceShape2D{
●doublepi=3.14;
●doublearea();
●}
5.1.2实现接口
接口
●接口的实现
●接口不能用new运算符直接产生对象,必须利用其特性设计新的类,再用新类来创建对象
●利用接口设计类的过程,称为接口的实现,使用implements关键字
●语法如下
●publicclass类名称implements接口名称{
●/*Bodiesfortheinterfacemethods*/
●/*Owndataandmethods.*/
●}
●必须实现接口中的所有方法
●来自接口的方法必须声明成public
5.1.2实现接口——例5_3
接口
●实现接口Insurable,声明汽车类实现例5.1中的Insurable接口,实现接口中的所有抽象方法
●publicclassCarimplementsInsurable{
●publicintgetPolicyNumber(){
●//writecodehere
●}
●publicdoublecalculatePremium(){
●//writecodehere
●}
●publicDategetExpiryDate(){
●//writecodehere
●}
●publicintgetCoverageAmount(){
●//writecodehere
●}
●publicintgetMileage(){//新添加的方法
●//writecodehere
●}
●}
5.1.2实现接口——对象转型
接口
●对象可以被转型为其所属类实现的接口类型
●getPolicyNumber、calculatePremium是Insurable接口中声明的方法
●getMileage是Car类新添加的方法,Insurable接口中没有声明此方法
●Car jetta=newCar();
●Insurable item=(Insurable)jetta;//对象转型为接口类型
●item.getPolicyNumber();
●item.calculatePremium();
●item.getMileage(); //接口中没有声明此方法,不可以
●jetta.getMileage(); //类中有此方法,可以
●((Car)item).getMileage();//转型回原类,可调用此方法了
5.1.2实现接口——例5_4
接口
●声明Circle与Rectangle两个类实现Shape2D接口
classCircleimplementsShape2D
{
doubleradius;
publicCircle(doubler)
{
radius=r;
}
publicdoublearea()
{
return(pi*radius*radius);
}
}
classRectangleimplementsShape2D
{
intwidth,height;
publicRectangle(intw,inth)
{
width=w;
height=h;
}
publicdoublearea()
{
return(width*height);
}
}
5.1.2实现接口——例5_4运行结果
接口
●测试类
●publicclassInterfaceTester{
●publicstaticvoidmain(Stringargs[]){
●Rectanglerect=newRectangle(5,6);
●System.out.println("Areaofrect="+rect.area());
●Circlecir=newCircle(2.0);
●System.out.println("Areaofcir="+cir.area());
●}
●}
●运行结果
●Areaofrect=30.0
●Areaofcir=12.56
5.1.2实现接口——例5_5
接口
●声明接口类型的变量,并用它来访问对象
●publicclassVariableTester{
●publicstaticvoidmain(String[]args)
●{
●Shape2Dvar1,var2;
●var1=newRectangle(5,6);
●System.out.println("Areaofvar1="+var1.area());
●var2=newCircle(2.0);
●System.out.println("Areaofvar2="+var2.area());
●}
●}
●输出结果
●Areaofvar1=30.0
●Areaofvar2=12.56
5.1.2实现接口——MovableObject接口
接口
●MovableObject接口定义了所有“可移动对象”能做的事情
●publicinterface MovableObject{
●publicboolean start();
publicvoid stop();
publicboolean turn(intdegrees);
publicdouble fuelRemaining();
publicvoid changeSpeed(doublekmPerHour);
●}
5.1.2实现接口——MovableObject接口的实现
接口
●Plane、Car、Train、Boat分别实现MovableObject接口
●publicclassPlaneimplements MovableObject{
●publicint seatCapacity;
●publicCompany owner;
●publicDate lastRepairDate;
●//实现MovalbelObject接口的所有方法
●publicbooleanstart(){//启动飞机,成功则返回true}
●publicvoidstop(){//停止}
●publicbooleanturn(intdegrees){//转向,成功则返回true}
●publicdoublefuelRemaining(){//返回燃料剩余量}
●publicvoidchangeSpeed(doublekmPerHour){//改变速度}
●//plane类自己的方法:
●publicDategetLastRepairDate(){//...}
●publicdoublecalculateWindResistance(){//....}
●}
5.1.2实现接口——RemoteControl类
接口
●为MovableObjects安装遥控器(remotecontrol)
●publicclassRemoteControl{
privateMovableObject machine;
●RemoteControl(MovableObjectm){machine=m;}
//按下“启动”按钮:
publicvoidstart()
●{
● booleanokay=machine.start();
if(!
okay)display("NoResponseonstart");
//...
}
●}
●remotecontrol构造方法的形参类型为MovableObject,它可以是Plane,Car,Train,Boat,等等
5.1.3多重继承
接口
●多重继承
●Java的设计以简单实用为导向,不允许一个类有多个父类
●但允许一个类可以实现多个接口,通过这种机制可实现多重继承
●一个类实现多个接口的语法如下
●[类修饰符]class类名称implements接口1,接口2,…
●{
●……
●}
5.1.3多重继承——Car的例子
接口
●Car类可以实现接口Insurable,Drivable,Sellable
●publicclassCarimplementsInsurable,Drivable,Sellable
●{
....
●}
5.1.3多重继承——例5_6
接口
●声明Circle类实现接口Shape2D和Color
●Shape2D具有pi与area()方法,用来计算面积
●Color则具有setColor方法,可用来赋值颜色
●通过实现这两个接口,Circle类得以同时拥有这两个接口的成员,达到了多重继承的目的
●interfaceShape2D{//声明Shape2D接口
●finaldoublepi=3.14;//数据成员一定要初始化
●publicabstractdoublearea();//抽象方法
●}
●interfaceColor{
●voidsetColor(Stringstr);//抽象方法
●}
5.1.3多重继承——例5_6
接口
classCircleimplementsShape2D,Color//实现Circle类
{
doubleradius;
Stringcolor;
publicCircle(doubler)//构造方法
{
radius=r;
}
publicdoublearea()//定义area()的处理方式
{
return(pi*radius*radius);
}
publicvoidsetColor(Stringstr)//定义setColor()的处理方式
{
color=str;
System.out.println("color="+color);
}
}
5.1.3多重继承——例5_6运行结果
接口
●测试类
●publicclassMultiInterfaceTester{
●publicstaticvoidmain(Stringargs[]){
●Circlecir;
●cir=newCircle(2.0);
●cir.setColor("blue");
●System.out.println("Area="+cir.area());
●}
●}
●输出结果
●color=blue
●Area=12.56
5.1.4接口的扩展
接口
●接口的扩展
●接口可通过扩展的技术派生出新的接口
●原来的接口称为基本接口(baseinterface)或父接口(superinterface)
●派生出的接口称为派生接口(derivedinterface)或子接口(subinterface)
●派生接口不仅可以保有父接口的成员,同时也可加入新成员以满足实际问题的需要
●实现接口的类也必须实现此接口的父接口
●接口扩展的语法
●interface子接口的名称extends父接口的名称1,父接口的名称2,…
●{
●……
●}
5.1.4接口的扩展——例5_7
接口
●Shape是父接口,Shape2D与Shape3D是其子接口。
Circle类及Rectangle类实现接口Shape2D,而Box类及Sphere类实现接口Shape3D
5.1.4接口的扩展——例5_7
接口
●部分代码如下
●//声明Shape接口
●interfaceShape{
●doublepi=3.14;
●voidsetColor(Stringstr);
●}
●//声明Shape2D接口扩展了Shape接口
●interfaceShape2DextendsShape{
●doublearea();
●}
5.1.4接口的扩展——例5_7
接口
classCircleimplementsShape2D{
doubleradius;
Stringcolor;
publicCircle(doubler){radius=r;}
publicdoublearea(){
return(pi*radius*radius);
}
publicvoidsetColor(Stringstr){
color=str;
System.out.println("color="+color);
}
}
publicclassExtendsInterfaceTester{//测试类
publicstaticvoidmain(String[]args){
Circlecir;
cir=newCircle(2.0);
cir.setColor("blue");
System.out.println("Area="+cir.area());
}
}
5.1.4接口的扩展——例5_7运行结果
接口
●运行结果
●color=blue
●Area=12.56
●说明
●首先声明了父接口Shape,然后声明其子接口Shape2D
●之后声明类Circle实现Shape2D子接口,因而在此类内必须明确定义setColor()与area()方法的处理方式
●最后在主类中我们声明了Circle类型的变量cir并创建新的对象,最后通过cir对象调用setColor()与area()方法
5.1.4接口的扩展——Insurable接口的例子
接口
●FixedInsurable和DepreciatingInsurable接口
●都继承了Insurable接口
●实现它们类也必须实现Insurable接口中的所有方法
●publicinterfaceDepreciatingInsurableextends Insurable{
publicdoublecomputeFairMarketValue();
●}
●publicinterfaceFixedInsurableextends Insurable{
publicintgetEvaluationPeriod();
●}
5.2塑型
●塑型(type-casting)
●又称为类型转换
●方式
●隐式(自动)的类型转换
●显式(强制)的类型转换
5.2.1塑型的概念
塑型
●塑型的对象包括
●基本数据类型
●将值从一种形式转换成另一种形式
●引用变量
●将对象暂时当成更一般的对象来对待,并不改变其类型
●只能被塑型为
●任何一个父类类型
●对象所属的类实现的一个接口
●被塑型为父类或接口后,再被塑型回其本身所在的类
5.2.1塑型的概念——一个例子
塑型
●Manager对象
●可以被塑型为Employee、Person、Object或Insurable,
●不能被塑型为Customer、Company或Car
5.2.1塑型的概念——隐式(自动)的类型转换
塑型
●基本数据类型
●相容类型之间存储容量低的自动向存储容量高的类型转换
●引用变量
●被塑型成更一般的类
●Employeeemp;
●emp=newManager();//将Manager类型的对象直接赋给
●//Employee类的引用变量,系统会
●//自动将Manage对象塑型为Employee类
●被塑型为对象所属类实现的接口类型
●Carjetta=newCar();
●Insurableitem=jetta;
5.2.1塑型的概念——显式(强制)的类型转换
塑型
●基本数据类型
●(int)871.34354;//结果为871
●(char)65;//结果为‘A’
●(long)453;//结果为453L
●引用变量:
还原为本来的类型
●Employeeemp;
●Managerman;
●emp=newManager();
●man=(Manager)emp;//将emp强制塑型为本来的类型
5.2.2塑型的应用
塑型
●塑型应用的场合包括
●赋值转换
●赋值号右边的表达式类型或对象转换为左边的类型
●方法调用转换
●实参的类型转换为形参的类型
●算数表达式转换
●算数混合运算时,不同类型的项转换为相同的类型再进行运算
●字符串转换
●字符串连接运算时,如果一个操作数为字符串,一个操作数为数值型,则会自动将数值型转换为字符串
5.2.2塑型的应用
塑型
●当一个类对象被塑型为其父类后,它提供的方法会减少
●当Manager对象被塑型为Employee之后,它只能接收getName()及getEmployeeNumber()方法,不能接收getSalary()方法
●将其塑型为本来的类型后,又能接收getSalary()方法了
5.2.3方法的查找
塑型
●如果在塑型前和塑型后的类中都提供了相同的方法,如果将此方法发送给塑型后的对象,那么系统将会调用哪一个类中的方法?
●实例方法的查找
●类方法的查找
5.2.3方法的查找——实例方法的查找
塑型
●从对象创建时的类开始,沿类层次向上查找
Manager man=newManager();
Employee emp1=newEmployee();
Employee emp2=(Employee)man;
putePay();//调用Employee类中的computePay()方法