版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第4章继承与多态性第4章继承与多态性14.1继承的基本概念顾名思义,继承就是子将父的东西承接过来。图4-1动物类别之间的继承【提示】继承需要符合IS-A(是一种)关系,也就是子类是父类的一种,如老虎是食肉动物的一种。4.1继承的基本概念顾名思义,继承就是子将父的东西承接过2Java继承的特点1)继承关系是传递的。若类C继承类B,类B继承类A,则类C既有从类B那里继承下来的属性与方法,也有从类A那里继承下来的属性与方法,还可以有自己新定义的属性和方法。2)继承简化了人们对事物的认识和描述,能清晰体现相关类间的层次结构关系。3)继承提供了软件复用功能。若类B继承类A,那么建立类B时只需要再描述与基类(类A)不同的少量特征(数据成员和成员方法)即可。这种做法能减小代码和数据的冗余度,大大增加程序的重用性。4)继承通过增强一致性来减少模块间的接口和界面,大大增加了程序的易维护性。Java继承的特点1)继承关系是传递的。若类C继承类B,类34.2Java继承的实现4.2.1继承的语法在Java中使用extends关键字实现继承关系,格式如下:[访问控制方式]class<子类名>extends<父类名>{......//成员定义 }4.2Java继承的实现4.2.1继承的语法44.2.1继承的语法【实例4-1】继承的使用classPerson{
privateStringname;//姓名
private
intage;//年龄
publicStringgetName(){
returnname; }
public
voidsetName(Stringname){
=name; }
public
intgetAge(){
returnage; }
public
voidsetAge(intage){
this.age=age; } }classStudentextendsPerson{
privateStringschool;//学校
private
intgrade;//年级
publicStringgetSchool(){
returnschool; }
public
voidsetSchool(Stringschool){
this.school=school; }
public
intgetGrade(){
returngrade; }
public
voidsetGrade(intgrade){
this.grade=grade; }}4.2.1继承的语法【实例4-1】继承的使用classS54.2.1继承的语法public
classInheritDemo{
public
static
voidmain(String[]args){ Studentstu=newStudent();//新建学生对象 stu.setName("张三");//访问从父类继承的方法 stu.setAge(20);//访问从父类继承的方法 stu.setSchool("哈佛大学");//访问本类定义的方法 stu.setGrade(2);//访问本类定义的方法 System.out.println("姓名:"+stu.getName()+",年龄:"+stu.getAge()+"学校:"+stu.getSchool()+",年级:"+stu.getGrade()); }}4.2.1继承的语法publicclassInheri64.2.1继承的语法4.2.1继承的语法74.2.2protected访问控制方式父类和子类是一般类和特殊类关系,子类是需要扩展父类的功能的,在扩展父类的功能时,可能会需要使用到从父类继承的私有成员,但父类的私有成员,在子类中不能直接访问。为此,Java提供了protected访问控制方式来解决这个问题。protected访问控制方式介于private和public之间,用protected修饰的类里的成员,向所有子类和同一个包的其它类开放其访问权限。
4.2.2protected访问控制方式父类和子类是一般84.2.3super关键字与子类对象实例化过程子类对象实例中这些继承下来的非静态数据成员所占用的内存区域为子类对象实例中的父类子对象。注意父类子对象本身相当于一个父类对象实例。Java语言的每一个对象实例也有一个特殊的私有数据成员,称为super,用来引用该父类子对象。super也是一个引用变量,其类型则是它所属的对象实例的父类类型。4.2.3super关键字与子类对象实例化过程子类对象实94.2.3super关键字与子类对象实例化过程【实例4-2】子类对象实例化classPerson{
publicPerson(){ System.out.println("我是Person类的构造方法"); }}classStudentextendsPerson{
publicStudent(){ System.out.println("我是Student类的构造方法"); }}public
classSuperDemo1{
public
static
voidmain(String[]args){ Studentstu=newStudent();//新建学生对象 }}图4-5运行结果4.2.3super关键字与子类对象实例化过程【实例4-2104.2.3super关键字与子类对象实例化过程【实例4-3】super关键字classPerson{
privateStringname;//姓名
private
intage;//年龄
publicPerson(Stringname,intage){
=name;
this.age=age; }
publicStringgetName(){
returnname; }
public
intgetAge(){
returnage; }}4.2.3super关键字与子类对象实例化过程【实例4-3114.2.3super关键字与子类对象实例化过程classStudentextendsPerson{
privateStringschool;//学校
private
intgrade;//年级
publicStudent(Stringname,intage,Stringschool,intgrade){
super(name,age);//调用父类构造方法,初始化从父类继承的对象属性
this.school=school;
this.grade=grade; }
publicStringgetSchool(){
returnschool; }
public
intgetGrade(){
returngrade; }}4.2.3super关键字与子类对象实例化过程class124.2.3super关键字与子类对象实例化过程public
classSuperDemo2{
public
static
voidmain(String[]args){ Studentstu=newStudent("张三",20,"哈佛大学",2);//新建学生对象 System.out.println("姓名:"+stu.getName()+",年龄:"+stu.getAge()+"学校:“+stu.getSchool()+",年级:"+stu.getGrade()); }}4.2.3super关键字与子类对象实例化过程public134.2.4方法重写(Override)方法重写也称为方法覆盖或方法重定义
classVehicle{
public
voidrun(){ System.out.println("交通工具在跑!"); }}classTruckextendsVehicle{ @Override//表示方法重写的Java注解
public
voidrun(){ System.out.println("货车在地上跑!"); }}classAirplaneextendsVehicle{ @Override//表示方法重写的Java注解
public
voidrun(){ System.out.println("飞机在天上飞!"); }}4.2.4方法重写(Override)方法重写也称为方法144.2.5final关键字final在Java中表示最终的意思,使用final可以声明类、属性和方法:1)使用final可以声明常量,常量不能修改,定义时要赋初值;例如:final
intNUM=0;2)使用final声明的方法不能被子类重写;3)使用final声明的类不能有子类。4.2.5final关键字final在Java中表示最终154.3继承与子类型类A继承类B,则类型A是类型B的子类型。Java语言允许祖先类类型的引用变量指向后代类类型的对象。例如,类GraduateStudent是类Student的子类,下述语句是合法的:Students=newGraduateStudent();类似的如果一个方法的形参是超类类型,那么方法调用时可以传给它一个子类对象作为实参,例如对于一个方法voidf(Studentd);可以这样来调用它:GraduateStudents=newGraduateStudent();f(s);//子类对象作为实参4.3继承与子类型类A继承类B,则类型A是类型B的子类型164.4抽象类与多态性4.4.1抽象类的引入抽象类往往用来表征我们在对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。4.4抽象类与多态性4.4.1抽象类的引入174.4.2抽象方法在抽象类中创建的没有具体实现的,必须要子类重写的方法称为抽象方法。抽象方法用关键字abstract进行修饰,这种方法只声明返回的数据类型、方法名称和所需的参数,没有方法体,也就是说抽象方法只需要声明而不需要实现。声明一个抽象方法的基本格式如下:abstract<方法返回值类型><方法名>(参数列表);例如: abstract
voidf();4.4.2抽象方法在抽象类中创建的没有具体实现的,必须要184.4.3抽象类的定义【实例4-4】如何定义抽象类及抽象方法示例abstract
classFruit{//定义抽象类
publicStringcolor;//定义颜色成员变量
publicFruit(){//定义构造方法 color="绿色";//对变量color进行初始化 }
public
abstract
voidharvest();//定义抽象方法}classAppleextendsFruit{
public
voidharvest(){ System.out.println("苹果已经收获!"); }}4.4.3抽象类的定义【实例4-4】如何定义抽象类及抽象194.4.3抽象类的定义classOrangeextendsFruit{
public
voidharvest(){ System.out.println("桔子已经收获!"); }}public
classAbstractClassDemo{
public
static
voidmain(String[]args){ Fruitf1=newApple();//父类引用指向子类对象 f1.harvest();//通过父类引用调用子类对象的重写方法 f1=newOrange(); f1.harvest(); }}4.4.3抽象类的定义classOrangeexten204.4.4多态性(Polymorphism)“Polymorphism(多态)”一词来自希腊语,意为“多种形式”。指的是一个程序中同名的不同方法共存的情况。多态有编译时(静态)多态和运行时(动态)多态。编译时多态是通过方法重载实现的;运行时多态是通过方法覆盖实现(子类覆盖父类方法)的。4.4.4多态性(Polymorphism)“Polym214.4.4多态性(Polymorphism)【实例4-5】一个经典的抽象图形类和它的具体子类的例子程序4-5ShapeDemo.javaimportjava.util.*;abstract
classShape{//Shape类是几个具体图形类的抽象父类
public
abstract
voiddraw();//定义抽象方法}classRectangleextendsShape{//Rectangle类是Shape类的一个具体子类@Override//表示方法重写的Java注解
public
voiddraw(){System.out.println("画矩形");}}4.4.4多态性(Polymorphism)【实例4-5】224.4.4多态性(Polymorphism)classCircleextendsShape{//Circle类也是Shape类的一个具体子类@Override
public
voiddraw(){System.out.println("画圆");}}classTriangleextendsShape{//Triangle类是Shape类的一个具体子类@Override
public
voiddraw(){System.out.println("画三角形");}}4.4.4多态性(Polymorphism)classC234.4.4多态性(Polymorphism)//ShapeDemo类中随机生成矩形、圆、三角形,然后用Shape类型的引用调用public
classShapeDemo{Randomrand=newRandom();//创建一个随机数类,具体使用可参看Java帮助文档
publicShapecreateShape(){
intc=rand.nextInt(3);//产生0-2之间的随机整数Shapes=null;
switch(c){//根据产生的随机整数创建对象
case0:s=newRectangle();
break;
case1:s=newCircle();
break;
case2:s=newTriangle();
break;}
returns;}4.4.4多态性(Polymorphism)//Shape244.4.4多态性(Polymorphism)
public
static
voidmain(String[]args){ShapeDemodemo=newShapeDemo();Shape[]shapes=newShape[5];//定义5个Shape类的引用
for(inti=0;i<shapes.length;i++){ //使5个Shape类的引用指向随机生成的子类对象shapes[i]=demo.createShape();}
for(inti=0;i<shapes.length;i++){shapes[i].draw();//同样的消息,不同的响应}}}4.4.4多态性(Polymorphism)public254.5继承的使用要点1、抽象类是用来继承的,具体类不是用来继承的。
2、抽象类应当拥有尽可能多的共同代码。3、抽象类应当拥有尽可能少的数据。
4.5继承的使用要点1、抽象类是用来继承的,具体类不是用264.5继承的使用要点4.5继承的使用要点274.5继承的使用要点4、使用继承的条件。当以下的条件全部被满足时,才应当使用继承关系:(1)继承代表“一般/特殊”关系,其中超类代表一般,而子类代表特殊,子类是超类的一个特殊种类,而不是超类的一个角色,也就是要区分“Has-A”与“Is-A”两种关系的不同。Has-A关系应当使用聚合描述,而只有Is-A关系才符合继承关系。(2)子类具有扩展超类的责任,而不是具有注销掉(Nullify)超类特性的责任。(3)只有从分类学角度上有意义时,才可以使用继承,不要从工具类继承。4.5继承的使用要点4、使用继承的条件。284.5继承的使用要点4.5继承的使用要点294.6instanceof运算符例如,Manager和Contractor都是抽象类Employee的子类publicvoidmethod(Employeee){if(einstanceofManager){…//dosomethingasaManager}elseif(einstanceofContractor){…//dosomethingasaContractor}}然而,这种做法通常被认为是没有好好利用面向对象中的多态性,这样的设计实际很糟糕,代码难以维护。4.6instanceof运算符例如,Manager和C304.7Object类4.7.1基本作用Object类是Java类层中的最高层类,是所有类的超类。所有的类构成了一棵以Object类为顶点的继承树。结果是所有的类都继承了Object类声明的接口和方法,这一特性在程序设计中有举足轻重的作用,可以使用这种“通用”对象类型进行“通用”程序设计,所以在很多类库设计上都采用Object类型作为方法的参数类型。4.7Object类4.7.1基本作用314.7Object类4.7.2主要方法1、equals()方法用于测试某个对象是否同另一个对象相等。它在Object类中的实现是判断两个对象是否指向同一块内存区域(直接用“==”进行比较)。2、toString()方法返回该对象的字符串表示。3、finalize()方法当垃圾回收器将要释放无用对象的内存时,先调用该对象的finalize方法。4.7Object类4.7.2主要方法324.8基本类型的包装类序号基本数据类型包装类1byteByte2booleanBoolean3shortShort4charCharacter5intInteger6longLong7floatFloat8doubleDouble4.8基本类型的包装类序号基本数据类型包装类1byteB334.8基本类型的包装类对于包装类说,这些类的用途主要包含两种:作为和基本数据类型对应的类类型存在,方便涉及到对象的操作。包含每种基本数据类型的相关属性如最大值、最小值等,以及相关的操作方法。通过包装类可以获取本类型的最大和最小值,例如,下面语句会打印出整型的最大和最小值:System.out.println(Integer.MAX_VALUE);
//2147483647
System.out.println(Integer.MIN_VALUE);
//-2147483648【注意】数值类型的包装类中都有
MAX_VALUE
和
MIN_VALUE
两个静态常量,代表此类型的基本类型的最大值和最小值。4.8基本类型的包装类对于包装类说,这些类的用途主要包含两344.8基本类型的包装类
int和Integer与String的转换两个常用的方法:parseInt和valueOf,它们都是静态方法。int
i=Integer.parseInt("123");
//把String转换为intStrings1=Integer.toString(i);//把int转换为StringIntegerb=Integer.valueOf("123");
//把String转换为IntegerStrings2=b.toString();//把Integer转换为String4.8基本类型的包装类
int和Integer与Strin354.9Java接口4.9.1Java接口的概念Java接口类似于纯抽象类,只包含常量和抽象方法,而没有变量和具体方法。Java接口从更深层次的理解,是定义(规范,约束)与实现的分离。
Java接口本身没有任何实现,所以,Java接口比Java抽象类更抽象化。Java接口的方法只能是抽象的和公开的,Java接口不能有构造方法,Java接口可以有public的、静态的final属性。4.9Java接口4.9.1Java接口的概念364.9.2Java接口的定义例如,下面定义一个Collection(集合)接口:interfaceCollection{ intMAX_NUM=100;//定义的常量,缺省是public、final和static的
//以下是声明的方法,缺省是public和abstract的 voidadd(Objectobj); voiddelete(Objectobj); Objectfind(Objectobj); intcurrentCount();}4.9.2Java接口的定义例如,下面定义一个Collec374.9.3Java接口的实现classFIFOQueueimplementsCollection{voidadd(Objectobj){......}//具体实现略,以下同voiddelete(Objectobj){......}Objectfind(Objectobj){......}intcurrentCount{......}}4.9.3Java接口的实现384.9.4Java接口类型的使用classInterfaceType{publicstaticvoidmain(Stringargs[]){Collectionc=newFIFOQueue();......c.add(obj);//通过接口引用调用对象中的接口实现方法......}}4.9.4Java接口类型的使用classInterfa394.9.5Java接口与多态性【实例4-6】一个利用接口实现运行时多态性的例子interfaceDoor{
public
voidopen();//抽象开门方法
public
voidclose();//抽象关门方法}classHouseimplementsDoor{//房子类实现了Door接口
public
voidopen(){ System.out.println("打开了房子的门"); }
public
voidclose(){ System.out.println("关闭了房子的门"); } }4.9.5Java接口与多态性【实例4-6】一个利用接口实404.9.5Java接口与多态性classCarimplementsDoor{//汽车类实现了Door接口
public
voidopen(){ System.out.println("打开了汽车的门"); }
public
voidclose(){ System.out.println("关闭了汽车的门"); } } 4.9.5Java接口与多态性classCarimpl414.9.5Java接口与多态性public
classInterfacePolymorphismDemo{
public
static
voidmain(String[]args){Doordoor=null;door=newHouse();//接口引用指向房子对象door.open();//通过接口引用调用接口中的方法door.close();//通过接口引用调用接口中的方法door=newCar();//接口引用指向汽车对象door.open();//通过接口引用调用接口中的方法door.close();//通过接口引用调用接口中的方法}}4.9.5Java接口与多态性publicclassI424.9.6Java接口的深入理解1、接口是对可插人性的保证
1)关联的可插入性例如:不要使用下面的声明语句:Vectoremployees=newVector();//Vector是Java的一个类而应该使用下面的声明语句:Listemployees=newVector();//List是Java的一个接口
这样作的好处是,在决定将Vector换成ArrayList(Vector类和ArrayList类都是Java类库中的集合类)时,程序中需要改动得语句很少,只需用下面语句替换前面的语句:Listemployees=newArrayList();//ArrayList类也实现了List接口4.9.6Java接口的深入理解1、接口是对可插人性的保434.9.6Java接口的深入理解2)调用的可插入性publicclassExample{ListmyList;//定义接口类型的引用属性publicExample(ListaList){myList=aList;//通过构造方法参数给myList属性赋值}publicintgetSize(){returnmyList.size()//通过接口引用调用对象的方法}publicstaticvoidmain(Stringargs[]){Vectorv=newVector();Exampleem=newExample(v);System.out.println(em.getSize());//会调用Vector对象的size()方法ArrayLista=newArrayList();em=newExample(a);System.out.println(em.getSize());//会调用ArrayList对象的size()方法}}4.9.6Java接口的深入理解2)调用的可插入性444.9.6Java接口的深入理解2.Java接口是针对抽象编程的保证针对抽象编程,不要针对具体编程。在程序中应当主要使用Java接口和抽象类将内部和外部耦合起来。换言之,应当使用Java接口和抽象类而不是具体类进行变量的类型声明、参量的类型声明、方法的返回类型声明以及数据类型的转换等。当然,更好的做法是仅仅使用Java接口,而不使用抽象类来做到上面这些。在理想的情况下,一个具体Java类应当只实现Java接口和抽象类中声明过的方法,而不应当给出多余的方法(思考为什么?)。4.9.6Java接口的深入理解2.Java接口是针对抽454.10注解(Annotation)4.10.1Annotation简介简单的说,注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,之后,Java编译器、开发工具和其他程序可以用反射来了解程序中的类及各种元素上有无何种标记,看有什么标记,就去干相应的事。4.10注解(Annotation)4.10.1An464.10.2Java提供的几个基本注解(1)@Override能实现编译时检查,可以为子类的重写方法添加该注释,以声明该方法是用于覆盖父类中的方法。如果该方法不是覆盖父类的方法,将会在编译时报错。例如,为某类重写toString()方法却写成了tostring(),如果为该方法添加了@Override注释,将会在编译时报错。(2)@SuppressWarnings该注解的作用是阻止编译器发出某些警告信息。常见参数:deprecation:过时的类或方法警告。unchecked:执行了未检查的转换时警告。(3)@Deprecated该注解的作用是标记某个过时的类或方法。当编程人员使用这些方法时,将会在编译时显示提示信息。4.10.2Java提供的几个基本注解(1)@Ov474.11应用实例4.11.1Java接口的实际应用——简单工厂设计模式
一、简单工厂模式概述
简单工厂模式是类的创建模式,又叫做静态工厂方法(StaticFactoryMethod)模式。简单工厂模式是由一个工厂对象决定创建出那一种产品类的实例。
4.11应用实例4.11.1Java接口的实际应用——484.11.1Java接口的实际应用——简单工厂设计模式二、模式意图简单工厂模式的主要意图是隐藏对象创建这一任务的复杂性。客户通常不指定要创建的具体类,而是面向接口或抽象类进行编码,让工厂类负责创建具体的对象。通常工厂类有一个返回抽象类或接口类型对象的静态方法,客户通常(并非总是)会提供某种信息,然后工厂类根据提供的信息来创建并返回一个类的对象。将创建对象的责任提取出来的好处是允许客户代码不依赖于具体类,遵循依赖倒转原则:“针对抽象编程,不要针对具体编程”。另一个好处是把创建对象的代码集中起来,如果需要修改生成的对象,可以很容易找到并修改,而不需要修改客户代码。4.11.1Java接口的实际应用——简单工厂设计模式二、494.11.1Java接口的实际应用——简单工厂设计模式三、模式结构与参与者该模式中包含的角色及其职责:1、工厂(Factory)角色简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。2、抽象产品(IProduct)角色简单工厂模式所创建的所有对象的父类或实现的接口,它负责描述所有实例所共有的公共接口。3、具体产品(ConcreteProduct)角色
是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。4.11.1Java接口的实际应用——简单工厂设计模式三、504.11.1Java接口的实际应用——简单工厂设计模式4.11.1Java接口的实际应用——简单工厂设计模式514.11.1Java接口的实际应用——简单工厂设计模式四、实例——电子商务网站货运公司的选择对于一个电子商务网站,假设是根据订单货物重量的大小来确定使用哪一家货运公司,在这里可以采用简单工厂模式来创建相应的货运公司对象。4.11.1Java接口的实际应用——简单工厂设计模式四、524.11.1Java接口的实际应用——简单工厂设计模式classOrder{//订单类
private
doubleweight;//订单货物重量
publicOrder(doubleweight){
super();
this.weight=weight; }
public
doublegetWeight(){
returnweight; } //为了简单,其它成员省略}//货运公司接口interfaceIShippingCourier{
voidtransport();//运输方法}4.11.1Java接口的实际应用——简单工厂设计模式cl534.11.1Java接口的实际应用——简单工厂设计模式classCompanyAimplementsIShippingCourier{//具体货运公司 @Override
public
voidtransport(){ System.out.println("由CompanyA公司运送");//简单示意性代码 } }classCompanyBimplementsIShippingCourier{//具体货运公司 @Override
public
voidtransport(){ System.out.println("由CompanyB公司运送");//简单示意性代码 } }4.11.1Java接口的实际应用——简单工厂设计模式cl544.11.1Java接口的实际应用——简单工厂设计模式//创建具体货运公司类对象的工厂类classShippingCourierFactory{ //根据货物重量创建相应的货运公司类对象的静态方法
public
staticIShippingCouriercreatShippingCourier(Orderorder){
if(order.getWeight()>100){
return
newCompanyA(); }else
return
newCompanyB(); }}4.11.1Java接口的实际应用——简单工厂设计模式//554.11.1Java接口的实际应用——简单工厂设计模式classOrderService{//退货处理服务类
public
voiddispatch(Orderorder){//处理退货单的方法 //调用工厂类的静态方法创建退货处理类对象 IShippingCouriershippingCourier= ShippingCourierFactory.creatShippingCourier(order); shippingCourier.transport(); } }4.11.1Java接口的实际应用——简单工厂设计模式cl564.11.1Java接口的实际应用——简单工厂设计模式public
classSimpleFactoryPatternDemo{//应用程序主类
public
static
voidmain(String[]args){ OrderServiceorderService=newOrderService(); Orderorder1=newOrder(90); orderService.dispatch(order1); Orderorder2=newOrder(110); orderService.dispatch(order2);}}4.11.1Java接口的实际应用——简单工厂设计模式pu574.11.2抽象类的实际应用——模版方法设计模式一、模版方法模式概述模板方法(TemplateMethod)模式是一种非常简单而又经常使用的设计模式,先创建一个父类,把其中的一个或多个方法留给子类去实现,这实际上就是在使用模板模式。所谓的模板模式可以这样来理解:在一个类中定义一个算法,但将此算法的某些细节留到子类中去实现。更近一步可以这样来理解:准备一个抽象类,将部分逻辑以具体方法的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类以不同的方法实现这些抽象方法,从而对剩余的逻辑有不同的实现。4.11.2抽象类的实际应用——模版方法设计模式一、模版方58二、模式意图将一个类的基本部分抽取出来放到一个基类中,这样它就不必重复出现在几个派生类里。三、模式结构与参与者
抽象模板角色:
1、定义了一个或多个抽象操作,以便让子类实现。
2、定义并实现了一个模板方法(指抽象模板类里调用抽象方法和具体方法的方法)。
具体模板角色:
1、实现父类所定义的一个或多个抽象方法。
2、每一个抽象模板角色都可以有任意多个具体模板角色与之对应。
3、每一个具体模板角色都可以给出这些抽象方法的不同实现。4.11.2抽象类的实际应用——模版方法设计模式二、模式意图4.11.2抽象类的实际应用——模版方法设计模式594.11.2抽象类的实际应用——模版方法设计模式4.11.2抽象类的实际应用——模版方法设计模式604.11.2抽象类的实际应用——模版方法设计模式四、实例——电子商务网站的退货处理系统
退货单目前有两种:无条件退货单和有缺陷退货单。无条件退货允许客户退还商品并接收全额退款,但需要减去最初邮寄和包装的费用,然后将商品添加到库存中。如果客户收到一件有缺陷的商品并希望退货,就形成了有问题的退货,该退款包括最初支付的邮寄和包装的费用,退货后将商品返厂。4.11.2抽象类的实际应用——模版方法设计模式四、实例——614.11.2抽象类的实际应用——模版方法设计模式处理退货分为两步,一个是计算退款数量,另一个是退货后处理,这对于两类退货是一样的,但对于两类退货每步具体处理是不一样的。这时,我们可以使用模板方法模式定义一个抽象退货处理类,在其中定义两个抽象方法完成两步处理,再定义一个具体的退货处理方法调用这两个抽象方法(具体实现留给子类去实现)来完成退货处理。定义两个具体退货处理子类,给出父类两个抽象方法的具体实现。实际使用时,根据退货单类型创建具体子类对象,调用从父类继承的退货处理方法来完成退货处理。4.11.2抽象类的实际应用——模版方法设计模式处理退货分为624.11.2抽象类的实际应用——模版方法设计模式4.11.2抽象类的实际应用——模版方法设计模式634.11.2抽象类的实际应用——模版方法设计模式enumReturnType{//退货单类型
FaultReturn,//表示有缺陷退货类型
NoQuibblesReturn//表示无条件退货类型}classReturnOrder{//退货单类//退货单类型,为了简单,定义成公有成员
publicReturnTypereturnType; //为了简单,其它成员省略}4.11.2抽象类的实际应用——模版方法设计模式enumR644.11.2抽象类的实际应用——模版方法设计模式abstract
classReturnProcessTemplate{//抽象退货处理类 //下面两个是抽象方法,留给子类实现
protected
abstract
voidGenerateReturn(ReturnOrderreturnOrder);
protected
abstract
voidCalculateRefund(ReturnOrderreturnOrder); //具体方法,调用两个抽象方法
public
voidprocess(ReturnOrderreturnOrder){ GenerateReturn(returnOrder); CalculateRefund(returnOrder); } }4.11.2抽象类的实际应用——模版方法设计模式abstra654.11.2抽象类的实际应用——模版方法设计模式//无条件退货处理类classNoQuibblesReturnProssextendsReturnProcessTemplate{ @Override//表示方法重写的Java注解
protected
voidGenerateReturn(ReturnOrderreturnOrder){ System.out.println("将商品添加到库存中");//简单示意性代码 } @Override
protected
voidCalculateRefund(ReturnOrderreturnOrder){ System.out.println("只退货款");//简单示意性代码 } }4.11.2抽象类的实际应用——模版方法设计模式//无条件退664.11.2抽象类的实际应用——模版方法设计模式//有缺陷退货处理类classFaultReturnProssextendsReturnProcessTemplate{ @Override
protected
voidGenerateReturn(ReturnOrderreturnOrder){ System.out.println("将商品返厂");//简单示意性代码 } @Override
protected
voidCalculateRefund(ReturnOrderreturnOrder){ System.out.println("全额退款");//简单示意性代码 } }4.11.2抽象类的实际应用——模版方法设计模式//有缺陷退674.11.2抽象类的实际应用——模版方法设计模式classReturnProcessFactory{//创建退货处理类对象的工厂类 //根据退货单类型创建相应的退货处理类对象的静态方法
public
staticReturnProcessTemplatecreatReturnProcess(ReturnTypereturnType){
switch(returnType){
case
FaultReturn:
return
newFaultReturnPross();
case
NoQuibblesReturn:
return
newNoQuibblesReturnPross();
default:return
null; } }}4.11.2抽象类的实际应用——模版方法设计模式class684.11.2抽象类的实际应用——模版方法设计模式classReturnService{//退货处理服务类
public
voidprocess(ReturnOrderreturnOrder){//处理退货单的方法 //调用工厂类的静态方法创建退货处理类对象 ReturnProcessTemplatereturnProcess=ReturnProcessFactory.creatReturnProcess(returnOrder.returnType);//调用退货处理类对象的方法处理退货 returnPcess(returnOrder); } }4.11.2抽象类的实际应用——模版方法设计模式class694.11.2抽象类的实际应用——模版方法设计模式public
classTemplateMethodPatternDemo{//应用程序主类
public
static
voidmain(String[]args){ ReturnOrderfaultReturnOrder=newReturnOrder();//生成退货单对象 //设置退货单为有缺陷类型 faultReturnOrder.returnType=ReturnType.FaultReturn; //创建退货处理服务类对象 ReturnServicereturnService=newReturnService(); returnScess(faultReturnOrder);//调用处理退货单的方法 ReturnOrdernoQuibblesReturnOrder=newReturnOrder();//生成退货单对象 //设置退货单为无条件退货类型 noQuibblesReturnOrder.returnType=ReturnType.NoQuibblesReturn; returnScess(noQuibblesReturnOrder);//调用处理退货单的方法}}4.11.2抽象类的实际应用——模版方法设计模式public70第4章继承与多态性第4章继承与多态性714.1继承的基本概念顾名思义,继承就是子将父的东西承接过来。图4-1动物类别之间的继承【提示】继承需要符合IS-A(是一种)关系,也就是子类是父类的一种,如老虎是食肉动物的一种。4.1继承的基本概念顾名思义,继承就是子将父的东西承接过72Java继承的特点1)继承关系是传递的。若类C继承类B,类B继承类A,则类C既有从类B那里继承下来的属性与方法,也有从类A那里继承下来的属性与方法,还可以有自己新定义的属性和方法。2)继承简化了人们对事物的认识和描述,能清晰体现相关类间的层次结构关系。3)继承提供了软件复用功能。若类B继承类A,那么建立类B时只需要再描述与基类(类A)不同的少量特征(数据成员和成员方法)即可。这种做法能减小代码和数据的冗余度,大大增加程序的重用性。4)继承通过增强一致性来减少模块间的接口和界面,大大增加了程序的易维护性。Java继承的特点1)继承关系是传递的。若类C继承类B,类734.2Java继承的实现4.2.1继承的语法在Java中使用extends关键字实现继承关系,格式如下:[访问控制方式]class<子类名>extends<父类名>{......//成员定义 }4.2Java继承的实现4.2.1继承的语法744.2.1继承的语法【实例4-1】继承的使用classPerson{
privateStringname;//姓名
private
intage;//年龄
publicStringgetName(){
returnname; }
public
voidsetName(Stringname){
=name; }
public
intgetAge(){
returnage; }
public
voidsetAge(intage){
this.age=age; } }classStudentextendsPerson{
privateStringschool;//学校
private
intgrade;//年级
publicStringgetSchool(){
returnschool; }
public
voidsetSchool(Stringschool){
this.school=school; }
public
intgetGrade(){
returngrade; }
public
voidsetGrade(intgrade){
this.grade=grade; }}4.2.1继承的语法【实例4-1】继承的使用classS754.2.1继承的语法public
classInheritDemo{
public
static
voidmain(String[]args){ Studentstu=newStudent();//新建学生对象 stu.setName("张三");//访问从父类继承的方法 stu.setAge(20);//访问从父类继承的方法 stu.setSchool("哈佛大学");//访问本类定义的方法 stu.setGrade(2);//访问本类定义的方法 System.out.println("姓名:"+stu.getName()+",年龄:"+stu.getAge()+"学校:"+stu.getSchool()+",年级:"+stu.getGrade()); }}4.2.1继承的语法publicclassInheri764.2.1继承的语法4.2.1继承的语法774.2.2protected访问控制方式父类和子类是一般类和特殊类关系,子类是需要扩展父类的功能的,在扩展父类的功能时,可能会需要使用到从父类继承的私有成员,但父类的私有成员,在子类中不能直接访问。为此,Java提供了protected访问控制方式来解决这个问题。protected访问控制方式介于private和public之间,用protected修饰的类里的成员,向所有子类和同一个包的其它类开放其访问权限。
4.2.2protected访问控制方式父类和子类是一般784.2.3super关键字与子类对象实例化过程子类对象实例中这些继承下来的非静态数据成员所占用的内存区域为子类对象实例中的父类子对象。注意父类子对象本身相当于一个父类对象实例。Java语言的每一个对象实例也有一个特殊的私有数据成员,称为super,用来引用该父类子对象。super也是一个引用变量,其类型则是它所属的对象实例的父类类型。4.2.3super关键字与子类对象实例化过程子类对象实794.2.3super关键字与子类对象实例化过程【实例4-2】子类对象实例化classPerson{
publicPerson(){ System.out.println("我是Person类的构造方法"); }}classStudentextendsPerson{
publicStudent(){ System.out.println("我是Student类的构造方法"); }}public
classSuperDemo1{
public
static
voidmain(String[]args){ Studentstu=newStudent();//新建学生对象 }}图4-5运行结果4.2.3super关键字与子类对象实例化过程【实例4-2804.2.3super关键字与子类对象实例化过程【实例4-3】super关键字classPerson{
privateStringname;//姓名
private
intage;//年龄
publicPerson(Stringname,intage){
=name;
this.age=age; }
publicStringgetName(){
returnname; }
public
intgetAge(){
returnage; }}4.2.3super关键字与子类对象实例化过程【实例4-3814.2.3super关键字与子类对象实例化过程classStudentextendsPerson{
privateStringschool;//学校
private
intgrade;//年级
publicStudent(Stringname,intage,Stringschool,intgrade){
super(name,age);//调用父类构造方法,初始化从父类继承的对象属性
this.school=school;
this.grade=grade; }
publicStringgetSchool(){
returnschool; }
public
intgetGrade(){
returngrade; }}4.2.3super关键字与子类对象实例化过程class824.2.3super关键字与子类对象实例化过程public
classSuperDemo2{
public
static
voidmain(String[]args){ Studentstu=newStudent("张三",20,"哈佛大学",2);//新建学生对象 System.out.println("姓名:"+stu.getName()+",年龄:"+stu.getAge()+"学校:“+stu.getSchool()+",年级:"+stu.getGrade()); }}4.2.3super关键字与子类对象实例化过程public834.2.4方法重写(Override)方法重写也称为方法覆盖或方法重定义
classVehicle{
public
voidrun(){ System.out.println("交通工具在跑!"); }}classTruckextendsVehicle{ @Override//表示方法重写的Java注解
public
voidrun(){ System.out.println("货车在地上跑!"); }}classAirplaneextendsVehicle{ @Override//表示方法重写的Java注解
public
voidrun(){ System.out.println("飞机在天上飞!"); }}4.2.4方法重写(Override)方法重写也称为方法844.2.5final关键字final在Java中表示最终的意思,使用final可以声明类、属性和方法:1)使用final可以声明常量,常量不能修改,定义时要赋初值;例如:final
intNUM=0;2)使用final声明的方法不能被子类重写;3)使用final声明的类不能有子类。4.2.5final关键字final在Java中表示最终854.3继承与子类型类A继承类B,则类型A是类型B的子类型。Java语言允许祖先类类型的引用变量指向后代类类型的对象。例如,类GraduateStudent是类Student的子类,下述语句是合法的:Students=newGraduateStudent();类似的如果一个方法的形参是超类类型,那么方法调用时可以传给它一个子类对象作为实参,例如对于一个方法voidf(Studentd);可以这样来调用它:GraduateStudents=newGraduateStudent();f(s);//子类对象作为实参4.3继承与子类型类A继承类B,则类型A是类型B的子类型864.4抽象类与多态性4.4.1抽象类的引入抽象类往往用来表征我们在对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。4.4抽象类与多态性4.4.1抽象类的引入874.4.2抽象方法在抽象类中创建的没有具体实现的,必须要子类重写的方法称为抽象方法。抽象方法用关键字abstract进行修饰,这种方法只声明返回的数据类型、方法名称和所需的参数,没有方法体,也就是说抽象方法只需要声明而不需要实现。声明一个抽象方法的基本格式如下:abstract<方法返回值类型><方法名>(参数列表);例如: abstract
voidf();4.4.2抽象方法在抽象类中创建的没有具体实现的,必须要884.4.3抽象类的定义【实例4-4】如何定义抽象类及抽象方法示例abstract
classFruit{//定义抽象类
publicStringcolor;//定义颜色成员变量
publicFruit(){//定义构造方法 color="绿色";//对变量color进行初始化 }
public
abstract
voidharvest();//定义抽象方法}classAppleextendsFruit{
public
voidharvest(){ System.out.println("苹果已经收获!"); }}4.4.3抽象类的定义【实例4-4】如何定义抽象类及抽象894.4.3抽象类的定义classOrangeextendsFruit{
public
voidharvest(){ System.out.println("桔子已经收获!"); }}public
classAbstractClassDemo{
public
static
voidmain(String[]args){ Fruitf1=newApple();//父类引用指向子类对象 f1.harvest();
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 钟表维修工创新意识水平考核试卷含答案
- 眼科护理操作流程手册
- 螺旋分选工QC管理评优考核试卷含答案
- 电离辐射计量员复试能力考核试卷含答案
- 坚果果蔬籽加工工交接强化考核试卷含答案
- 染色小样工绩效目标评优考核试卷含答案
- 复合超硬材料制造工班组协作强化考核试卷含答案
- 制粉工基础能力考核试卷含答案
- 裁边拉毛工岗位责任制知识考核试卷含答案
- 井下采煤工安全素养能力考核试卷含答案
- 2026广东佛山市南海区狮山镇村(社区)招聘60人笔试备考试题及答案解析
- 2026-2027学年人教版四年级上册数学月考试卷(第一、二单元)(含答案)
- 2026年秋季四年级数学上册第一单元测试卷(人教版大数的认识含完整答案)
- 2026年北京市中考英语试卷真题及答案详解(精校打印版)
- 2026年秋人美版(新教材)小学美术四年级上册(全册)教学设计(附目录p153)
- 重庆数字资源集团招聘笔试题库2026
- 2026年平安岗前培训测试题及答案
- 2026年广东省公需课《人工智能赋能高质量发展》试题及答案
- DB44-T 2749-2025 黄金奈李生产技术规程
- JTT 1540-2025 低温改性沥青
- 人教版七年级单词全
评论
0/150
提交评论