1、4.1 继承的基本概念 顾名思义,继承就是子将父的东西承接过来。动动物物食食草草动动物物食食肉肉动动物物牛牛马马狮狮子子老老虎虎图4-1 动物类别之间的继承【提示提示】继承需要符合IS-A(是一种)关系,也就是子类是父类的一种,如老虎是食肉动物的一种。Java继承的特点 1)继承关系是传递的。若类C继承类B,类B继承类A,则类C既有从类B那里继承下来的属性与方法,也有从类A那里继承下来的属性与方法,还可以有自己新定义的属性和方法。2)继承简化了人们对事物的认识和描述,能清晰体现相关类间的层次结构关系。3)继承提供了软件复用功能。若类B继承类A,那么建立类B时只需要再描述与基类(类A)不同的少量
2、特征(数据成员和成员方法)即可。这种做法能减小代码和数据的冗余度,大大增加程序的重用性。4)继承通过增强一致性来减少模块间的接口和界面,大大增加了程序的易维护性。4.2 Java继承的实现 4.2.1 继承的语法 在Java中使用extends关键字实现继承关系,格式如下:访问控制方式 class extends ./成员定义4.2.1 继承的语法【实例实例4-1】继承的使用继承的使用class Personprivate String name;/姓名private int age;/年龄public String getName()return name;public void setNa
3、me(String name)this.name=name;public int getAge()return age;public void setAge(int age)this.age=age;class Student extends Personprivate String school;/学校private int grade;/年级public String getSchool()return school;public void setSchool(String school)this.school=school;public int getGrade()return grad
4、e;public void setGrade(int grade)this.grade=grade;4.2.1 继承的语法public class InheritDemo public static void main(String args)Student stu=new Student();/新建学生对象stu.setName(张三);/访问从父类继承的方法stu.setAge(20);/访问从父类继承的方法stu.setSchool(哈佛大学);/访问本类定义的方法stu.setGrade(2);/访问本类定义的方法 System.out.println(姓名:+stu.getName(
5、)+,年龄:+stu.getAge()+学校:+stu.getSchool()+,年级:+stu.getGrade();4.2.1 继承的语法子类虽然继承了父类的私有成员,但在子类中不能直接访问的示例如下:图4-3 编译出错4.2.2 protected访问控制方式 父类和子类是一般类和特殊类关系,子类是需要扩展父类的功能的,在扩展父类的功能时,可能会需要使用到从父类继承的私有成员,但父类的私有成员,在子类中不能直接访问。为此,Java提供了protected访问控制方式来解决这个问题。protected访问控制方式介于private和public之间,用用protected修饰的类里修饰的类
6、里的成员,向所有子类和同一个包的其它类开放其的成员,向所有子类和同一个包的其它类开放其访问权限。访问权限。把Person类的name的访问控制方式修改为protected:class Personprotected String name;/姓名 .class Student extends Person.public void printName()System.out.println(name=+name);付出了增加类之间耦合性的代价。专家们的建议是把类中的属性都定义成private的,然后设置访问方法为public或protected的。4.2.3 super关键字与子类对象实例化过程
7、 子类对象实例中这些继承下来的非静态数据成员所占用的内存区域为子类对象实例中的父类子对象。注意父类子对象本身相当于一个父类对象实例。Java 语言的每一语言的每一个对象实例也有一个特殊的私有数据成员,个对象实例也有一个特殊的私有数据成员,称为称为super,用来引用该父类子对象。,用来引用该父类子对象。super 也是一个引用变量,其类型则是它所属的对象实例的父类类型。4.2.3 super关键字与子类对象实例化过程【实例实例4-2】子类对象实例化class Personpublic Person()System.out.println(我是Person类的构造方法);class Studen
8、t extends Personpublic Student()System.out.println(我是Student类的构造方法);public class SuperDemo1 public static void main(String args)Student stu=new Student();/新建学生对象程序运行结果如下:我是Person类的构造方法我是Student类的构造方法4.2.3 super关键字与子类对象实例化过程【实例实例4-3】super关键字class Personprivate String name;/姓名private int age;/年龄public
9、 Person(String name,int age)this.name=name;this.age=age;public String getName()return name;public int getAge()return age;4.2.3 super关键字与子类对象实例化过程class Student extends Personprivate String school;/学校private int grade;/年级public Student(String name,int age,String school,int grade)super(name,age);/调用父类构
10、造方法,初始化从父类继承的对象属性this.school=school;this.grade=grade;public String getSchool()return school;public int getGrade()return grade;4.2.3 super关键字与子类对象实例化过程public class SuperDemo2 public static void main(String args)Student stu=new Student(张三,20,哈佛大学,2);/新建学生对象 System.out.println(姓名:+stu.getName()+,年龄:+st
11、u.getAge()+学校:“+stu.getSchool()+,年级:+stu.getGrade();程序运行结果如下:姓名:张三,年龄:20 学校:哈佛大学,年级:24.2.4 方法重写(Override)方法重写也称为方法覆盖或方法重定义方法重写也称为方法覆盖或方法重定义 class Vehicle public void run()System.out.println(交通工具在跑!);class Truck extends Vehicle Override /表示方法重写的Java注解public void run()System.out.println(货车在地上跑!);class
12、 Airplane extends Vehicle Override /表示方法重写的Java注解public void run()System.out.println(飞机在天上飞!);提示提示:子类不能重写父类的static方法。方法重写应遵循以下原则:1.重写的方法不能比父类被重写的方法产生更多的异常;(注:有关异常见第5章。)2.重写的方法不能比父类被重写的方法有更严格的访问权限。4.2.5 final关键字 final在Java中表示最终的意思,使用final可以声明类、属性和方法:1)使用final可以声明常量,常量不能修改,定义时要赋初值;例如:final int NUM=0;2
13、)使用final声明的方法不能被子类重写;3)使用final声明的类不能有子类。4.3 继承与子类型 类A继承类B,则类型A是类型B的子类型。Java语言允许祖先类类型的引用变量指向后代类语言允许祖先类类型的引用变量指向后代类类型的对象。类型的对象。例如,类GraduateStudent是类Student的子类,下述语句是合法的:Student s=new GraduateStudent();类似的如果一个方法的形参是超类类型,那么方法调用时可以传给它一个子类对象作为实参,例如对于一个方法void f(Student d);可以这样来调用它:GraduateStudent s=new Grad
14、uateStudent();f(s);/子类对象作为实参4.4 抽象类与多态性 4.4.1 抽象类的引入 抽象类往往用来表征我们在对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。4.4.2 抽象方法 在抽象类中创建的没有具体实现的,必须要子类重写的方法称为抽象方法。抽象方法用关键字abstract进行修饰,这种方法只声明返回的数据类型、方法名称和所需的参数,没有方法体,也就是说抽象方法只需要声明而不需要实现。声明一个抽象方法的基本格式如下:abstract (参数列表);例如:abstract void f();4.4.3 抽象类的定义【实例实例
15、4-4】如何定义抽象类及抽象方法示例abstract class Fruit /定义抽象类public String color;/定义颜色成员变量public Fruit()/定义构造方法color=绿色;/对变量color进行初始化public abstract void harvest();/定义抽象方法class Apple extends Fruit Overridepublic void harvest()System.out.println(苹果已经收获!);4.4.3 抽象类的定义class Orange extends Fruit Overridepublic void ha
16、rvest()System.out.println(桔子已经收获!);public class AbstractClassDemo public static void main(String args)Fruit f1=new Apple();/父类引用指向子类对象f1.harvest();/通过父类引用调用子类对象的重写方法f1=new Orange();f1.harvest();程序运行结果如下:苹果已经收获!桔子已经收获!4.4.4 多态性(Polymorphism)“Polymorphism(多态)”一词来自希腊语,意为“多种形式”。指的是一个程序中同名的不同方法共存的情况。多态有编
17、译时(静态)多态和运行时(动态)多态。编译时多态是通过方法重载实现的;运行时多态是通过方法覆盖实现(子类覆盖父类方法)的。4.4.4 多态性(Polymorphism)【实例实例4-5】一个经典的抽象图形类和它的具体子类的例子一个经典的抽象图形类和它的具体子类的例子import java.util.*;abstract class Shape /Shape类是几个具体图形类的抽象父类 public abstract void draw();/定义抽象方法class Rectangle extends Shape /Rectangle类是Shape类的一个具体子类 Override /表示方法重
18、写的Java注解 public void draw()System.out.println(画矩形);4.4.4 多态性(Polymorphism)class Circle extends Shape /Circle类也是Shape类的一个具体子类 Override public void draw()System.out.println(画圆);class ShapeUser/图形类的用户 /传入的实参只能是Shape类的具体子类对象public void showShape(Shape shape)shape.draw();/传入参数对象的draw方法4.4.4 多态性(Polymorph
19、ism)public class ShapeDemo/测试类 public static void main(String args)ShapeUser shapeUser=new ShapeUser();shapeUser.showShape(new Rectangle();/传入方法一个矩形对象 shapeUser.showShape(new Circle();/传入方法一个圆形对象 程序运行结果如下:画矩形画圆形总结一下,实现多态性的步骤如下:1.在抽象类中定义抽象方法;2.在抽象类的具体子类中重写抽象方法;3.让抽象类的对象引用指向具体子类对象;4.通过抽象类的对象引用调用抽象方法,会
20、绑定到具体子类中重写的抽象方法上。4.5 继承的使用要点 1、抽象类是用来继承的,具体类不是用来继、抽象类是用来继承的,具体类不是用来继承的。承的。2、抽象类应当拥有尽可能多的共同代码、抽象类应当拥有尽可能多的共同代码。3、抽象类应当拥有尽可能少的数据。、抽象类应当拥有尽可能少的数据。4.5 继承的使用要点4.5 继承的使用要点4、使用继承的条件。、使用继承的条件。当以下的条件全部被满足时,才应当使用继承关系:(1)继承代表“一般/特殊”关系,其中超类代表一般,而子类代表特殊,子类是超类的一个特殊种类,而不是超类的一个角色,也就是要区分“Has-A”与“Is-A”两种关系的不同。Has-A关系
21、应当使用聚合描述,而只有Is-A关系才符合继承关系。(2)子类具有扩展超类的责任,而不是具有注销掉(Nullify)超类特性的责任。(3)只有从分类学角度上有意义时,才可以使用继承,不要从工具类继承。4.5 继承的使用要点4.6 instanceof运算符 例如,Manager和Contractor都是抽象类Employee的子类 public void method(Employee e)if (e instanceof Manager)/do something as a Manager else if(e instanceof Contractor)/do something as a
22、Contractor 然而,这种做法通常被认为是没有好好利用面向对象中的多然而,这种做法通常被认为是没有好好利用面向对象中的多态性,这样的设计实际很糟糕,代码难以维护。态性,这样的设计实际很糟糕,代码难以维护。【实例实例4-6】使用多态性计算员工工资的例子。abstract class Employee/雇员抽象类public abstract void pay();/计算工资的抽象方法public void method()/发工资的方法pay();/会自动绑定到调用对象的pay方法class Manager extends Employee/经理类Overridepublic void p
23、ay()System.out.println(发给经理工资5000元);class Contractor extends Employee/合同工类Overridepublic void pay()System.out.println(发给合同工工资3000元);public class SalaryDemo public static void main(String args)Employee employee=new Manager();employee.method();employee=new Contractor();employee.method();程序运行结果如下:发给经理工
24、资5000元发给合同工工资3000元4.7 Object类 4.7.1 基本作用 Object 类是Java 类层中的最高层类,是所有类的超类。所有的类构成了一棵以Object类为顶点的继承树。结果是所有的类都继承了Object类声明的接口和方法,这一特性在程序设计中有举足轻重的作用,可以使用这种“通用”对象类型进行“通用”程序设计,所以在很多类库设计上都采用Object类型作为方法的参数类型。4.7 Object类4.7.2 主要方法 1、equals()方法方法用于测试某个对象是否同另一个对象相等。它在Object类中的实现是判断两个对象是否指向同一块内存区域(直接用“=”进行比较)。2、
25、toString()方法方法返回该对象的字符串表示。3、finalize()方法方法当垃圾回收器将要释放无用对象的内存时,先调用该对象的finalize方法。4.8 基本类型的包装类 序号序号基本数据类型基本数据类型包装类包装类1byteByte2booleanBoolean3shortShort4charCharacter5intInteger6longLong7floatFloat8doubleDouble4.8 基本类型的包装类对于包装类说,这些类的用途主要包含两种:作为和基本数据类型对应的类类型存在,方便涉及到对象的操作。包含每种基本数据类型的相关属性如最大值、最小值等,以及相关的操作
26、方法。通过包装类可以获取本类型的最大和最小值,例如,下面语句会通过包装类可以获取本类型的最大和最小值,例如,下面语句会打印出整型的最大和最小值:打印出整型的最大和最小值:System.out.println(Integer.MAX_VALUE);/2147483647 System.out.println(Integer.MIN_VALUE);/-2147483648【注意注意】数值类型的包装类中都有 MAX_VALUE 和 MIN_VALUE 两个静态常量,代表此类型的基本类型的最大值和最小值。4.8 基本类型的包装类 int和和Integer与与String的转换的转换两个常用的方法:pa
27、rseInt和valueOf,它们都是静态方法。int i=Integer.parseInt(123);/把String转换为intString s1=Integer.toString(i);/把int转换为StringInteger b=Integer.valueOf(123);/把String转换为IntegerString s2=b.toString();/把Integer转换为String4.9 Java接口 4.9.1 Java接口的概念 Java接口类似于纯抽象类,只包含常量和抽象方法,而没有变量和具体方法。Java接口从更深层次的理解,是定义(规范,约束)与实现的分离。Java接
28、口本身没有任何实现,所以,Java接口比Java抽象类更抽象化。Java接口的方法只能是抽象的和公开的,Java接口不能有构造方法,Java接口可以有public的、静态的final属性。4.9.2 Java接口的定义例如,下面定义一个Collection(集合)接口:interface Collection /定义的常量,缺省是public、final和static的final int MAX_NUM=100;/以下是声明的方法,缺省是public和abstract的void add(Object obj);void delete(Object obj);Object find(Object
29、 obj);int currentCount();4.9.3 Java接口的实现class FIFOQueue implements Collection public void add(Object obj)./具体实现略,以下同 public void delete(Object obj).public Object find(Object obj).public int currentCount.4.9.4 Java接口类型的使用class InterfaceType public static void main(String args)Collection c=new FIFOQue
30、ue();.c.add(obj);/通过接口引用调用对象中的接口实现方法 .4.9.5 Java接口与多态性【实例实例4-7】一个利用接口实现运行时多态性的例子一个利用接口实现运行时多态性的例子interface Doorpublic void open();/抽象开门方法public void close();/抽象关门方法class House implements Door /房子类实现了Door接口public void open()System.out.println(打开了房子的门);public void close()System.out.println(关闭了房子的门);4.
31、9.5 Java接口与多态性class Car implements Door/汽车类实现了Door接口public void open()System.out.println(打开了汽车的门);public void close()System.out.println(关闭了汽车的门);4.9.5 Java接口与多态性public class InterfacePolymorphismDemo public static void main(String args)Door door=null;door=new House();/接口引用指向房子对象 door.open();/通过接口引用调
32、用接口中的方法 door.close();/通过接口引用调用接口中的方法 door=new Car();/接口引用指向汽车对象 door.open();/通过接口引用调用接口中的方法 door.close();/通过接口引用调用接口中的方法 程序运行结果如下:打开了房子的门关闭了房子的门打开了汽车的门关闭了汽车的门4.9.6 Java接口的深入理解 1、接口是对可插人性的保证、接口是对可插人性的保证 1)关联的可插入性)关联的可插入性例如:不要使用下面的声明语句:例如:不要使用下面的声明语句:Vector employees=new Vector();/Vector是是Java的一个类的一个类
33、而应该使用下面的声明语句:而应该使用下面的声明语句:List employees=new Vector();/List是是Java的一个接口的一个接口 这样作的好处是,在决定将这样作的好处是,在决定将Vector换成换成ArrayList(Vector类和类和ArrayList类都是类都是Java类库中的集合类)时,程序中需要改动得语句类库中的集合类)时,程序中需要改动得语句很少,只需用下面语句替换前面的语句:很少,只需用下面语句替换前面的语句:List employees=new ArrayList();/ArrayList类也实现了类也实现了List接口接口 4.9.6 Java接口的深入
34、理解2)调用的可插入性)调用的可插入性 public class Example List myList;/定义接口类型的引用属性 public Example(List aList)myList=aList;/通过构造方法参数给myList 属性赋值 public int getSize()return myList.size()/通过接口引用调用对象的方法 public static void main(String args)Vector v=new Vector();Example em=new Example(v);System.out.println(em.getSize();/会
35、调用Vector对象的size()方法 ArrayList a=new ArrayList();em=new Example(a);System.out.println(em.getSize();/会调用ArrayList对象的size()方法 4.9.6 Java接口的深入理解 2.Java接口是针对抽象编程的保证接口是针对抽象编程的保证 针对抽象编程,不要针对具体编程。在程序中应当主要使用Java接口和抽象类将内部和外部耦合起来。换言之,应当使用Java接口和抽象类而不是具体类进行变量的类型声明、参量的类型声明、方法的返回类型声明以及数据类型的转换等。当然,更好的做法是仅仅使用Java接口
36、,而不使用抽象类来做到上面这些。在理想的情况下,一个具体Java类应当只实现Java接口和抽象类中声明过的方法,而不应当给出多余的方法(思考为什么?)。4.10 注解(Annotation)4.10.1 Annotation简介 简单的说,注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,之后,Java编译器、开发工具和其他程序可以用反射来了解程序中的类及各种元素上有无何种标记,看有什么标记,就去干相应的事。4.10.2 Java 提供的几个基本注解(1)Override 能实现编译时检查,可以为子类的重写方法添加该注释,以声明能实现编译时检查,可以为子类的重写方法添加该注释,以
37、声明该方法是用于覆盖父类中的方法。如果该方法不是覆盖父类的方法,该方法是用于覆盖父类中的方法。如果该方法不是覆盖父类的方法,将会在编译时报错。例如,为某类重写将会在编译时报错。例如,为某类重写toString()方法却写成了方法却写成了tostring(),如果为该方法添加了,如果为该方法添加了Override 注释,将会在编译时报注释,将会在编译时报错。错。(2)SuppressWarnings 该注解的作用是阻止编译器发出某些警告信息。常见参数:该注解的作用是阻止编译器发出某些警告信息。常见参数:deprecation:过时的类或方法警告。:过时的类或方法警告。unchecked:执行了未
38、检查的转换时警告。:执行了未检查的转换时警告。(3)Deprecated 该注解的作用是标记某个过时的类或方法。当编程人员使用这些该注解的作用是标记某个过时的类或方法。当编程人员使用这些方法时,将会在编译时显示提示信息。方法时,将会在编译时显示提示信息。4.11 应用实例 4.11.1 Java接口的实际应用简单工厂设计模式 一、简单工厂模式概述一、简单工厂模式概述 简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式。简单工厂模式是由一个工厂对象决定创建出那一种产品类的实例。4.11.1 Java接口的实际应用简单工厂设计模式二、模式意图二、模式意
39、图 简单工厂模式的主要意图是隐藏对象创建这一任务的复杂性。客户通常不指定要创建的具体类,而是面向接口或抽象类进行编码,让工厂类负责创建具体的对象。通常工厂类有一个返回抽象类或接口类型对象的静态方法,客户通常(并非总是)会提供某种信息,然后工厂类根据提供的信息来创建并返回一个类的对象。将创建对象的责任提取出来的好处是允许客户代码不依赖于具体类,遵循依赖倒转原则:“针对抽象编程,不要针对具体编程”。另一个好处是把创建对象的代码集中起来,如果需要修改生成的对象,可以很容易找到并修改,而不需要修改客户代码。4.11.1 Java接口的实际应用简单工厂设计模式三、模式结构与参与者三、模式结构与参与者该模
40、式中包含的角色及其职责:1、工厂(Factory)角色 简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。2、抽象产品(IProduct)角色 简单工厂模式所创建的所有对象的父类或实现的接口,它负责描述所有实例所共有的公共接口。3、具体产品(Concrete Product)角色是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。4.11.1 Java接口的实际应用简单工厂设计模式4.11.1 Java接口的实际应用简单工厂设计模式四、实例四、实例电子商务网站货运公司的选择电子商务网站货运公司的选择 对于一个电子商务网站
41、,假设是根据订单货物重量的大小来确定使用哪一家货运公司,在这里可以采用简单工厂模式来创建相应的货运公司对象。4.11.1 Java接口的实际应用简单工厂设计模式class Order /订单类private double weight;/订单货物重量public Order(double weight)super();this.weight=weight;public double getWeight()return weight;/为了简单,其它成员省略/货运公司接口interface IShippingCouriervoid transport();/运输方法4.11.1 Java接口的实
42、际应用简单工厂设计模式class CompanyA implements IShippingCourier /具体货运公司Overridepublic void transport()System.out.println(由CompanyA公司运送);/简单示意性代码class CompanyB implements IShippingCourier /具体货运公司Overridepublic void transport()System.out.println(由CompanyB公司运送);/简单示意性代码4.11.1 Java接口的实际应用简单工厂设计模式/创建具体货运公司类对象的工厂类c
43、lass ShippingCourierFactory /根据货物重量创建相应的货运公司类对象的静态方法public static IShippingCourier creatShippingCourier(Order order)if(order.getWeight()100)return new CompanyA();else return new CompanyB();4.11.1 Java接口的实际应用简单工厂设计模式class OrderService /退货处理服务类public void dispatch(Order order)/处理退货单的方法/调用工厂类的静态方法创建退货处
44、理类对象IShippingCourier shippingCourier=ShippingCourierFactory.creatShippingCourier(order);shippingCourier.transport();4.11.1 Java接口的实际应用简单工厂设计模式public class SimpleFactoryPatternDemo /应用程序主类 public static void main(String args)OrderService orderService=new OrderService();Order order1=new Order(90);orde
45、rService.dispatch(order1);Order order2=new Order(110);orderService.dispatch(order2);程序运行结果如下:由CompanyB公司运送由CompanyA公司运送4.11.2抽象类的实际应用模版方法设计模式 一、模版方法模式概述一、模版方法模式概述 模板方法(Template Method)模式是一种非常简单而又经常使用的设计模式,先创建一个父类,把其中的一个或多个方法留给子类去实现,这实际上就是在使用模板模式。所谓的模板模式可以这样来理解:在一个类中定义一个算法,但将此算法的某些细节留到子类中去实现。更近一步可以这样
46、来理解:准备一个抽象类,将部分逻辑以具体方法的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类以不同的方法实现这些抽象方法,从而对剩余的逻辑有不同的实现。二、模式意图二、模式意图 将一个类的基本部分抽取出来放到一个基类中,这样它就不必重复出现在几个派生类里。三、模式结构与参与者三、模式结构与参与者 抽象模板角色:1、定义了一个或多个抽象操作,以便让子类实现。2、定义并实现了一个模板方法(指抽象模板类里调用抽象方法和具体方法的方法)。具体模板角色:1、实现父类所定义的一个或多个抽象方法。2、每一个抽象模板角色都可以有任意多个具体模板角色与之对应。3、每一个具体模板角色都可以给出
47、这些抽象方法的不同实现。4.11.2抽象类的实际应用模版方法设计模式 4.11.2抽象类的实际应用模版方法设计模式4.11.2抽象类的实际应用模版方法设计模式 四、实例四、实例电子商务网站的退货处理系统电子商务网站的退货处理系统 退货单目前有两种:无条件退货单和有缺陷退货单。无条件退货允许客户退还商品并接收全额退款,但需要减去最初邮寄和包装的费用,然后将商品添加到库存中。如果客户收到一件有缺陷的商品并希望退货,就形成了有问题的退货,该退款包括最初支付的邮寄和包装的费用,退货后将商品返厂。4.11.2抽象类的实际应用模版方法设计模式 处理退货分为两步,一个是计算退款数量,另一个是退货后处理,这对
48、于两类退货是一样的,但对于两类退货每步具体处理是不一样的。这时,我们可以使用模板方法模式定义一个抽象退货处理类,在其中定义两个抽象方法完成两步处理,再定义一个具体的退货处理方法调用这两个抽象方法(具体实现留给子类去实现)来完成退货处理。定义两个具体退货处理子类,给出父类两个抽象方法的具体实现。实际使用时,根据退货单类型创建具体子类对象,调用从父类继承的退货处理方法来完成退货处理。4.11.2抽象类的实际应用模版方法设计模式4.11.2抽象类的实际应用模版方法设计模式enum ReturnType /退货单类型FaultReturn,/表示有缺陷退货类型NoQuibblesReturn /表示无
49、条件退货类型class ReturnOrder /退货单类 /退货单类型,为了简单,定义成公有成员public ReturnType returnType;/为了简单,其它成员省略4.11.2抽象类的实际应用模版方法设计模式abstract class ReturnProcessTemplate /抽象退货处理类/下面两个是抽象方法,留给子类实现protected abstract void GenerateReturn(ReturnOrder returnOrder);protected abstract void CalculateRefund(ReturnOrder returnOrde
50、r);/具体方法,调用两个抽象方法public void process(ReturnOrder returnOrder)GenerateReturn(returnOrder);CalculateRefund(returnOrder);4.11.2抽象类的实际应用模版方法设计模式/无条件退货处理类class NoQuibblesReturnPross extends ReturnProcessTemplateOverride /表示方法重写的Java注解protected void GenerateReturn(ReturnOrder returnOrder)System.out.printl