Presentation is loading. Please wait.

Presentation is loading. Please wait.

Programming in JAVA 第7章 类的继承性(下) 接口与多态.

Similar presentations


Presentation on theme: "Programming in JAVA 第7章 类的继承性(下) 接口与多态."— Presentation transcript:

1 Programming in JAVA 第7章 类的继承性(下) 接口与多态

2 目录 7.1 接口 7.2 塑型 7.3 多态的概念 7.4 多态的应用 7.5 构造方法与多态 7.6 内部类 7.7 本章小结

3 7.1 接口 接口 与抽象类一样都是定义多个类的共同属性 使抽象的概念更深入了一层,是一个“纯”抽象类,它只提供一种形式,并不提供实现
允许创建者规定方法的基本形式:方法名、自变量列表以及返回类型,但不规定方法主体 也可以包含基本数据类型的数据成员,但它们都默认为static和final

4 7.1.1 接口的作用及语法 接口的作用 接口 是面向对象的一个重要机制 实现多继承,同时免除C++中的多继承那样的复杂性
建立类和类之间的“协议” 把类根据其实现的功能来分别代表,而不必顾虑它所在的类继承层次;这样可以最大限度地利用动态绑定,隐藏实现细节 实现不同类之间的常量共享

5 7.1.1 接口的作用及语法 ——与抽象类的不同 接口 接口允许我们在看起来不相干的对象之间定义共同行为

6 <<Interface>>
7.1.1 接口的作用及语法 ——例7_1 接口 保险公司的例子 具有车辆保险、人员保险、公司保险等多种保险业务,各种业务的保险对象不同,但在对外提供服务方面具有相似性,如都需要计算保险费(premium)等,因此可声明一个Insurable 接口,并使不同的类实现这个接口 在UML图中,实现接口用带有空三角形的虚线表示 <<Interface>> Insurable Company Person Car

7 7.1.1 接口的作用及语法 接口的语法 接口 使用关键字interface声明接口 声明格式为
[接口修饰符] interface 接口名称 [extends 父接口名]{ …//方法的原型声明或静态常量 } 接口的数据成员一定要赋初值,且此值将不能再更改,允许省略final关键字 接口中的方法必须是“抽象方法”,不能有方法体,允许省略public及abstract关键字

8 7.1.1 接口的作用及语法 ——例7_1保险接口的声明 Insurable 接口声明如下,其中的方法都是抽象方法 接口
7.1.1 接口的作用及语法 ——例7_1保险接口的声明 接口 Insurable 接口声明如下,其中的方法都是抽象方法 public interface Insurable { public int getNumber(); public int getCoverageAmount(); public double calculatePremium(); public Date getExpiryDate(); }

9 7.1.1 接口的作用及语法 ——例7_2 声明一个接口Shape2D,可利用它来实现二维的几何形状类Circle和Rectangle 接口
7.1.1 接口的作用及语法 ——例7_2 接口 声明一个接口Shape2D,可利用它来实现二维的几何形状类Circle和Rectangle 把计算面积的方法声明在接口里 pi值是常量,把它声明在接口的数据成员里 interface Shape2D{    //声明Shape2D接口 final double pi=3.14;   //数据成员一定要初始化 public abstract double area(); //抽象方法 } 在接口的声明中,允许省略一些关键字,也可声明如下 interface Shape2D{ double pi=3.14; double area();

10 7.1.2 实现接口 接口的实现 接口 接口不能用new运算符直接产生对象,必须利用其特性构造新的类,再用新类来创建对象
利用接口构造类的过程,称为接口的实现 使用implements关键字,语法如下 public class 类名称 implements 接口名称 { /* Bodies for the interface methods */ /* Own data and methods. */ } 必须实现接口中的所有抽象方法 来自接口的方法必须声明成public

11 7.1.2 实现接口 ——例7_3 接口 实现接口Insurable,声明汽车类实现例6.1中的Insurable接口,实现接口中的所有抽象方法 public class Car implements Insurable { public int getPolicyNumber() { // write code here } public double calculatePremium() { public Date getExpiryDate() { public int getCoverageAmount() { public int getMileage() { //新添加的方法 //write code here

12 7.1.2 实现接口 ——对象转型 接口 对象可以被转型为其所属类实现的接口类型
7.1.2 实现接口 ——对象转型 参看例子TestInsurable.java 注意: 文件名必须与带有main方法的那个类同名。 接口也是一种类,所以如果定义成为了public ,则在同一个文件中的其他类也不能定义成为public。 接口 对象可以被转型为其所属类实现的接口类型 getPolicyNumber、calculatePremium是Insurable接口中声明的方法 getMileage是Car类新添加的方法,Insurable接口中没有声明此方法 Car  jetta = new Car(); Insurable  item = (Insurable)jetta; //对象转型为接口类型 item.getPolicyNumber(); item.calculatePremium(); item.getMileage();        // 接口中没有声明此方法,不可以 jetta.getMileage();       // 类中有此方法,可以 ((Car)item).getMileage(); // 转型回原类,可调用此方法了

13 7.1.2 实现接口 ——例7_4 接口 声明Circle与Rectangle两个类实现Shape2D接口 { {
7.1.2 实现接口 ——例7_4 接口 声明Circle与Rectangle两个类实现Shape2D接口 class Circle implements Shape2D { double radius; public Circle(double r) radius=r; } public double area() return (pi * radius * radius); class Rectangle implements Shape2D { int width,height; public Rectangle(int w,int h) width=w; height=h; } public double area() return (width * height);

14 7.1.2 实现接口 ——例7_4运行结果 接口 测试类 运行结果 public class InterfaceTester {
7.1.2 实现接口 ——例7_4运行结果 接口 测试类 public class InterfaceTester { public static void main(String args[]){ Rectangle rect=new Rectangle(5,6); System.out.println("Area of rect = " + rect.area()); Circle cir=new Circle(2.0); System.out.println("Area of cir = " + cir.area()); } 运行结果 Area of rect = 30.0 Area of cir = 12.56

15 7.1.2 实现接口 ——例7_5 接口 声明接口类型的变量,并用它来访问对象 输出结果
7.1.2 实现接口 ——例7_5 接口 声明接口类型的变量,并用它来访问对象 public class VariableTester { public static void main(String []args) { Shape2D var1,var2; var1=new Rectangle(5,6); System.out.println("Area of var1 = " + var1.area()); var2=new Circle(2.0); System.out.println("Area of var2 = " + var2.area()); } 输出结果 Area of var1 = 30.0 Area of var2 = 12.56

16 7.1.2 实现接口 ——MovableObject接口
public interface  MovableObject { public boolean    start(); public void       stop(); public boolean    turn(int degrees); public double     fuelRemaining(); public void       changeSpeed(double kmPerHour); }

17 7.1.2 实现接口 ——MovableObject接口的实现
Plane、Car、 Train、 Boat 分别实现 MovableObject 接口 public class Plane implements  MovableObject { public int   seatCapacity; public Company  owner; public Date  lastRepairDate; //实现MovalbelObject接口的所有方法 public boolean start() { //启动飞机,成功则返回true } public void stop() { //停止 } public boolean turn(int degrees) { //转向,成功则返回true} public double fuelRemaining() { //返回燃料剩余量 } public void changeSpeed(double kmPerHour) { //改变速度 } //plane类自己的方法: public Date getLastRepairDate() { //... } public double calculateWindResistance() { //....} }

18 7.1.2 实现接口 ——RemoteControl类
为 MovableObjects安装遥控器(remote control) public class RemoteControl {   private MovableObject   machine;     RemoteControl(MovableObject m) {machine = m; }   //按下“启动”按钮: public void start() {     boolean okay = machine.start();     if (!okay) display("No Response on start");     // } } remote control 构造方法的形参类型为 MovableObject,它可以是Plane, Car, Train, Boat, 等等

19 7.1.3 多重继承 多重继承 接口 Java的设计以简单实用为导向,不允许一个类有多个父类
但允许一个类可以实现多个接口,通过这种机制可实现多重继承 一个类实现多个接口的语法如下 [类修饰符] class 类名称 implements 接口1,接口2, … { … … }

20 7.1.3 多重继承 ——Car的例子 接口 Car类可以实现接口Insurable,Drivable,Sellable
public class Car implements Insurable, Drivable, Sellable {    .... }

21 7.1.3 多重继承 ——例7_6 声明Circle类实现接口Shape2D和Color 接口
7.1.3 多重继承 ——例7_6 接口 声明Circle类实现接口Shape2D和Color Shape2D具有pi与area()方法,用来计算面积 Color则具有setColor方法,可用来赋值颜色 通过实现这两个接口,Circle类得以同时拥有这两个接口的成员,达到了多重继承的目的 interface Shape2D{ //声明Shape2D接口 final double pi=3.14; //数据成员一定要初始化 public abstract double area(); //抽象方法 } interface Color{ void setColor(String str); //抽象方法

22 7.1.3 多重继承 ——例7_6 接口 class Circle implements Shape2D,Color // 实现Circle类 { double radius; String color; public Circle(double r) //构造方法 radius=r; } public double area() //定义area()的处理方式 return (pi*radius*radius); public void setColor(String str) //定义setColor()的处理方式 color=str; System.out.println("color="+color);

23 7.1.3 多重继承 ——例7_6运行结果 测试类 接口 输出结果 public class MultiInterfaceTester{
7.1.3 多重继承 ——例7_6运行结果 接口 测试类 public class MultiInterfaceTester{ public static void main(String args[]) { Circle cir; cir=new Circle(2.0); cir.setColor("blue"); System.out.println("Area = " + cir.area()); } 输出结果 color=blue Area = 12.56

24 7.1.4 接口的扩展 接口 接口的扩展 接口可通过扩展的技术派生出新的接口
原来的接口称为基本接口(base interface)或父接口(super interface) 派生出的接口称为派生接口(derived interface)或子接口(sub interface) 派生接口不仅可以保有父接口的成员,同时也可加入新成员以满足实际问题的需要 实现接口的类也必须实现此接口的父接口 接口扩展的语法 interface 子接口的名称 extends 父接口的名称1 { … … }

25 7.1.4 接口的扩展 ——例7_7 接口 Shape是父接口,Shape2D与Shape3D是其子接口。Circle类及Rectangle类实现接口Shape2D,而Box类及Sphere类实现接口Shape3D Shape接口 Shape2D接口 Shape3D接口 Sphere类 Box类 Rectangle类 Circle类

26 7.1.4 接口的扩展 ——例7_7 部分代码如下 接口 // 声明Shape接口 interface Shape{
7.1.4 接口的扩展 ——例7_7 接口 部分代码如下 // 声明Shape接口 interface Shape{ double pi=3.14; void setColor(String str); } //声明Shape2D接口扩展了Shape接口 interface Shape2D extends Shape { double area();

27 7.1.4 接口的扩展 ——例7_7 接口 class Circle implements Shape2D { double radius;
7.1.4 接口的扩展 ——例7_7 接口 class Circle implements Shape2D { double radius; String color; public Circle(double r) { radius=r; } public double area() { return (pi*radius*radius); } public void setColor(String str){ color=str; System.out.println("color="+color); public class ExtendsInterfaceTester{ //测试类 public static void main(String []args) { Circle cir; cir=new Circle(2.0); cir.setColor("blue"); System.out.println("Area = " + cir.area());

28 7.1.4 接口的扩展 ——例7_7运行结果 运行结果 接口 说明 color=blue Area = 12.56
7.1.4 接口的扩展 ——例7_7运行结果 接口 运行结果 color=blue Area = 12.56 说明 首先声明了父接口Shape,然后声明其子接口Shape2D 之后声明类Circle实现Shape2D子接口,因而在此类内必须明确定义setColor()与area()方法的处理方式 最后在主类中我们声明了Circle类型的变量cir并创建新的对象,最后通过cir对象调用setColor()与area()方法

29 7.1.4 接口的扩展 ——Insurable接口的例子
FixedInsurable 和DepreciatingInsurable接口 都继承了Insurable接口 实现它们类也必须实现Insurable接口中的所有方法 public interface DepreciatingInsurable extends  Insurable {     public double computeFairMarketValue(); } public interface FixedInsurable extends  Insurable {     public int getEvaluationPeriod();

30 7.2 塑型 塑型(type-casting) 又称为类型转换 方式 隐式(自动)的类型转换 显式(强制)的类型转换

31 7.2.1 塑型的概念 塑型的对象 引用变量 塑型 将对象暂时当成更一般的对象来对待,并不改变其类型 只能被塑型为 任何一个父类类型
对象所属的类实现的一个接口 被塑型为父类或接口后,再被塑型回其本身所在的类

32 <<Interface>>
7.2.1 塑型的概念 ——一个例子 塑型 Manager对象 可以被塑型为Employee、Person、Object或Insurable, 不能被塑型为Customer、Company或Car Object Person Employee Customer Manager Company Car <<Interface>> Insurable

33 7.2.1 塑型的概念 ——隐式(自动)的类型转换 引用变量 被塑型成更一般的类 塑型 Employee emp;
7.2.1 塑型的概念 ——隐式(自动)的类型转换 塑型 引用变量 被塑型成更一般的类 Employee emp; emp = new Manager(); Car jetta = new Car(); Insurable item = jetta;

34 7.2.1 塑型的概念 ——显式(强制)的类型转换 引用变量:还原为本来的类型 Employee emp; 塑型 Manager man;
7.2.1 塑型的概念 ——显式(强制)的类型转换 塑型 引用变量:还原为本来的类型 Employee emp; Manager man; emp = new Manager(); man = (Manager)emp; //将emp强制塑型为本来的类型

35 7.2.2 塑型的应用 塑型 当一个类对象被塑型为其父类后,它提供的方法会减少
当Manager对象被塑型为Employee之后,它只能接收getName()及getEmployeeNumber()方法,不能接收getSalary()方法 将其塑型为本来的类型后,又能接收getSalary()方法了

36 7.2.3 方法的查找 如果在塑型前和塑型后的类中都提供了相同的方法,如果将此方法发送给塑型后的对象,那么系统将会调用哪一个类中的方法?
实例方法 类方法

37 7.2.3 方法的查找 ——实例方法 塑型 Manager man = new Manager();
7.2.3 方法的查找 ——实例方法 塑型 Manager   man = new Manager(); Employee  emp1 = new Employee(); Employee  emp2 = (Employee)man; emp1.computePay(); // 调用Employee类中的computePay()方法 man.computePay();  // 调用Manager类中的computePay()方法 emp2.computePay(); // 调用Manager类中的computePay()方法

38 7.2.3 方法的查找 ——类方法 总是在变量声明时所属的类中进行查找 塑型 Manager man = new Manager();
7.2.3 方法的查找 ——类方法 塑型 总是在变量声明时所属的类中进行查找 Manager man = new Manager(); Employee emp1 = new Employee(); Employee emp2 = (Employee)man; man.expenseAllowance(); //in Manager emp1.expenseAllowance(); //in Employee emp2.expenseAllowance(); //in Employee!!!

39 7.3 多态的概念 多态 是指不同类型的对象可以响应相同的消息
从相同的基类派生出来的多个类型可被当作同一种类型对待,可对这些不同的类型进行同样的处理,由于多态性,这些不同派生类对象响应同一方法时的行为是有所差别的 例如 所有的Object类的对象都响应toString()方法 所有的BankAccount类的对象都响应deposit()方法

40 7.3.1 多态的目的 多态的目的 多态的概念 所有的对象都可被塑型为相同的类型,响应相同的消息 使代码变得简单且容易理解
使程序具有很好的“扩展性”

41 7.3.1 多态的目的 ——一个例子 多态的概念 绘图 希望能够画出任意子类型对象的形状,可以在Shape 类中声明几个绘图方法,对不同的实际对象,采用不同的画法 if (aShape instanceof Circle) aShape.drawCircle(); if (aShape instanceof Triangle) aShape.drawTriangle(); if (aShape instanceof Rectangle)aShape.drawRectangle();

42 7.3.1 多态的目的 ——一个例子 更好的方式 多态的概念 在每个子类中都声明同名的draw()方法 以后绘图可如下进行
7.3.1 多态的目的 ——一个例子 多态的概念 更好的方式 在每个子类中都声明同名的draw()方法 以后绘图可如下进行 Shape s = new Circle(); s.draw(); Circle属于Shape的一种,系统会执行自动塑型 当调用方法draw时,实际调用的是Circle.draw() 在程序运行时才进行绑定,接下来介绍绑定的概念

43 7.3.2 绑定的概念 绑定 多态的概念 指将一个方法调用同一个方法主体连接到一起 根据绑定时期的不同,可分为
早期绑定(静态绑定)——方法的重载 程序运行之前执行绑定 晚期绑定(动态绑定)——方法的重写 也叫作“动态绑定”或“运行期绑定 基于对象的类别,在程序运行时执行绑定

44 7.3.2 绑定的概念 ——例7_8 仍以绘图为例,所有类都放在binding包中 多态的概念 基类Shape建立了一个通用接口
7.3.2 绑定的概念 ——例7_8 多态的概念 仍以绘图为例,所有类都放在binding包中 基类Shape建立了一个通用接口 class Shape { void draw() {} void erase() {} } 派生类覆盖了draw方法,为每种特殊类型的几何形状都提供独一无二的行为 class Circle extends Shape { void draw() { System.out.println("Circle.draw()"); } void erase() { System.out.println("Circle.erase()"); }

45 7.3.2 绑定的概念 ——例7_8 多态的概念 class Square extends Shape { void draw()
7.3.2 绑定的概念 ——例7_8 多态的概念 class Square extends Shape { void draw() { System.out.println("Square.draw()"); } void erase() { System.out.println("Square.erase()"); } } class Triangle extends Shape { { System.out.println("Triangle.draw()"); } { System.out.println("Triangle.erase()"); }

46 7.3.2 绑定的概念 ——例7_8 多态的概念 对动态绑定进行测试如下 public class BindingTester{
7.3.2 绑定的概念 ——例7_8 多态的概念 对动态绑定进行测试如下 public class BindingTester{ public static void main(String[] args) { Shape[] s = new Shape[9]; int n; for(int i = 0; i < s.length; i++) { n = (int)(Math.random() * 3); switch(n) { case 0: s[i] = new Circle(); break; case 1: s[i] = new Square(); break; case 2: s[i] = new Triangle(); } for(int i = 0; i < s.length; i++) s[i].draw();

47 7.3.2 绑定的概念 ——例7_8运行结果 多态的概念 运行结果 说明 Square.draw() Triangle.draw()
7.3.2 绑定的概念 ——例7_8运行结果 多态的概念 运行结果 Square.draw() Triangle.draw() Circle.draw() 说明 编译的时候是无法知道s数组元素的具体类型到底是什么 运行的时候才能确定究竟是什么类型,所以是动态绑定 在主方法的循环体中,每次根据运行时产生的随机数生成指向一个Circle、Square或者Triangle的引用,所以每次运行都可能有不同的结果

48 7.4 多态的应用 多态的应用 多态的概念 技术基础 向上塑型技术:一个父类的引用变量可以指向不同的子类对象
动态绑定技术:运行时根据父类引用变量所指对象的实际类型执行相应的子类方法,从而实现多态性

49 7.4 多态的应用(续) ——例7_9 多态的概念 声明一个抽象类Driver及两个子类FemaleDriver及MaleDriver
7.4 多态的应用(续) ——例7_9 多态的概念 声明一个抽象类Driver及两个子类FemaleDriver及MaleDriver 在Diver类中声明了抽象方法drives,在两个子类中对这个方法进行了重写 public abstract class Driver { public Driver( ) { } public abstract void drives( ); }

50 7.4 多态的应用(续) ——例7_9 多态的概念 public class FemaleDriver extends Driver {
7.4 多态的应用(续) ——例7_9 多态的概念 public class FemaleDriver extends Driver { public FemaleDriver( ) { } public void drives( ) { System.out.println("A Female driver drives a vehicle."); } public class MaleDriver extends Driver { public MaleDriver( ) { } System.out.println("A male driver drives a vehicle.");

51 7.4 多态的应用(续) ——例7_9 多态的概念 运行结果 public class Test1 {
7.4 多态的应用(续) ——例7_9 多态的概念 public class Test1 { static public void main(String [ ] args) Driver a = new FemaleDriver( ); Driver b = new MaleDriver( ); a.drives( ); b.drives( ); } 运行结果 A Female driver drives a vehicle. A male driver drives a vehicle.

52 7.4 多态的应用(续) ——例7_9改进 多态的概念 所有类都放在drive包中
7.4 多态的应用(续) ——例7_9改进 多态的概念 所有类都放在drive包中 试想有不同种类的交通工具(vehicle),如公共汽车(bus)及小汽车(car),由此可以声明一个抽象类Vehicle及两个子类Bus及Car 对前面的drives方法进行改进,使其接收一个Vehicle类的参数,当不同类型的交通工具被传送到此方法时,可以输出具体的交通工具

53 7.4 多态的应用(续) ——例7_9改进 多态的概念 测试代码可改写如下: 并希望输出下面的结果
7.4 多态的应用(续) ——例7_9改进 多态的概念 测试代码可改写如下: public class DriverTest { static public void main(String [ ] args) { Driver a = new FemaleDriver( ); Driver b = new MaleDriver( ); Vehicle x = new Car( ); Vehicle y = new Bus( ); a.drives(x); b.drives(y); } 并希望输出下面的结果 A female driver drives a Car. A male driver drives a bus.

54 7.4 多态的应用(续) ——例7_9改进 Vehicle及其子类声明如下 多态的概念
7.4 多态的应用(续) ——例7_9改进 多态的概念 Vehicle及其子类声明如下 public abstract class Vehicle { private String type; public Vehicle( ) { } public Vehicle(String s) { type = s; } public abstract void drivedByFemaleDriver(); public abstract void drivedByMaleDriver(); }

55 7.4 多态的应用(续) ——例7_9改进 多态的概念 public class Bus extends Vehicle {
7.4 多态的应用(续) ——例7_9改进 多态的概念 public class Bus extends Vehicle { public Bus( ) { } public void drivedByFemaleDriver() { System.out.println("A female driver drives a bus."); } public void drivedByMaleDriver() { System.out.println("A male driver drives a bus."); } } public class Car extends Vehicle { public Car( ) { } { System.out.println("A Female driver drives a car."); } { System.out.println("A Male driver drives a car."); }

56 7.4 多态的应用(续) ——例7_9改进 多态的概念 对FemaleDriver及MaleDriver类中的drives方法进行改进,在drives方法的定义体中不直接输出结果,而是调用Bus及Car类中的相应方法 public abstract class Driver { public Driver() { } public abstract void drives(Vehicle v ); } public class FemaleDriver extends Driver{ public FemaleDriver( ) { } public void drives(Vehicle v){ v.drivedByFemaleDriver(); } public class MaleDriver extends Driver{ public MaleDriver( ) { } public void drives(Vehicle v){ v.drivedByMaleDriver(); }

57 7.4 多态的应用(续) ——例7_9改进运行结果 运行结果 多态的概念 说明 A Female driver drives a car.
7.4 多态的应用(续) ——例7_9改进运行结果 多态的概念 运行结果 A Female driver drives a car. A male driver drives a bus. 说明 这种技术称为二次分发(“double dispatching”),即对输出消息的请求被分发两次 首先根据驾驶员的类型被发送给一个类 之后根据交通工具的类型被发送给另一个类

58 7.6 内部类 内部类 在另一个类或方法的定义中定义的类 可访问其外部类中的所有数据成员和方法成员 可对逻辑上相互联系的类进行分组
对于同一个包中的其他类来说,能够隐藏 可非常方便地编写事件驱动程序 声明方式 命名的内部类:可在类的内部多次使用 匿名内部类:可在new关键字后声明内部类,并立即创建一个对象 假设外层类名为Myclass,则该类的内部类名为 Myclass$c1.class (c1为命名的内部类名) Myclass$1.class (表示类中声明的第一个匿名内部类)

59 7.6 内部类 ——Parcel1.java 内部类 public class Parcel1 {
class Contents { //内部类 private int i = 11; public int value() { return i; } } class Destination { //内部类 private String label; Destination(String whereTo) { label = whereTo; } String readLabel() { return label; } public void ship(String dest) { Contents c = new Contents(); Destination d = new Destination(dest); System.out.println(d.readLabel());

60 7.6 内部类 ——Parcel1.java public static void main(String[] args) { 内部类 说明
Parcel1 p = new Parcel1(); p.ship("Tanzania"); } 说明 在Parcel1类中声明了两个内部类Contents、Destination 在ship方法中生成两个内部类对象,并调用了内部类中声明的一个方法

61 7.6 内部类 ——Parcel2.java 外部类的方法可以返回内部类的引用变量 内部类 public class Parcel2 {
class Contents { private int i = 11; public int value() { return i; } } class Destination { private String label; Destination(String whereTo) { label = whereTo; } String readLabel() { return label; } public Destination to(String s){ return new Destination(s); } public Contents cont() { return new Contents(); }

62 7.6 内部类 ——Parcel2.java 内部类 说明 Contents c = cont();
public void ship(String dest) { Contents c = cont(); Destination d = to(dest); System.out.println(d.readLabel()); } public static void main(String[] args) { Parcel2 p = new Parcel2(); p.ship("Tanzania"); Parcel2 q = new Parcel2(); Parcel2.Contents c = q.cont(); Parcel2.Destination d =q.to("Borneo"); 说明 to()方法返回内部类Destination的引用 cont()方法返回内部类Contents的引用

63 7.6 内部类 ——内部类实现接口 内部类实现接口 内部类 例子 可以完全不被看到,而且不能被调用
7.6 内部类 ——内部类实现接口 内部类 内部类实现接口 可以完全不被看到,而且不能被调用 可以方便实现“隐藏实现细则”。你所能得到的仅仅是指向基类(base class)或者接口的一个引用 例子 abstract class Contents { abstract public int value(); } interface Destination { String readLabel();

64 7.6 内部类 ——Parcel3.java 内部类 public class Parcel3 {
private class PContents extends Contents { private int i = 11; public int value() { return i; } } protected class PDestination implements Destination { private String label; private PDestination(String whereTo) { label = whereTo;} public String readLabel() { return label; } public Destination dest(String s) { return new PDestination(s); } public Contents cont() { return new PContents(); }

65 7.6 内部类 ——Parcel3测试 内部类 说明 class Test {
public static void main(String[] args) { Parcel3 p = new Parcel3(); Contents c = p.cont(); Destination d = p.dest("Tanzania"); // Illegal -- can't access private class: Parcel3.PContents c = p.new PContents(); } 说明 内部类PContents实现了抽象类Contents 内部类PDenstination实现了接口Destination 外部类Test中不能声明对private的内部类的引用

66 7.6 内部类 ——方法中的内部类 在方法内定义一个内部类 内部类 为实现某个接口,产生并返回一个引用
7.6 内部类 ——方法中的内部类 内部类 在方法内定义一个内部类 为实现某个接口,产生并返回一个引用 为解决一个复杂问题,需要建立一个类,而又不想它为外界所用

67 7.6 内部类 ——匿名的内部类 内部类 public class Parcel6 { public Contents cont() {
7.6 内部类 ——匿名的内部类 内部类 public class Parcel6 { public Contents cont() { return new Contents() { private int i = 11; public int value() { return i; } }; } public static void main(String[] args) { Parcel6 p = new Parcel6(); Contents c = p.cont();

68 7.6 内部类 ——匿名的内部类 基类需要一个含参数的构造方法 例子 内部类 public class Parcel7 {
7.6 内部类 ——匿名的内部类 内部类 基类需要一个含参数的构造方法 例子 public class Parcel7 { public Wrapping wrap(int x) { return new Wrapping(x) { public int value() { return super.value() * 47; } }; } public static void main(String[] args) { Parcel7 p = new Parcel7(); Wrapping w = p.wrap(10);

69 7.7 本章小结 本章内容 本章要求 接口作用及语法 塑型的概念及应用 多态的概念及引用 构造方法的调用顺序及其中的多态方法
内部内的有关知识 本章要求 理解接口、塑型、多态的概念并能熟练应用 熟练掌握构造方法的调用顺序,理解编写时需要注意的问题 掌握内部类的语法结构及其应用场合


Download ppt "Programming in JAVA 第7章 类的继承性(下) 接口与多态."

Similar presentations


Ads by Google