1、第4章 继承与多态性 4.1 继承的基本概念 顾名思义,继承就是子将父的东西承接过来。动动物物食食草草动动物物食食肉肉动动物物牛牛马马狮狮子子老老虎虎图4-1 动物类别之间的继承【提示提示】继承需要符合IS-A(是一种)关系,也就是子类是父类的一种,如老虎是食肉动物的一种。Java继承的特点 1)继承关系是传递的。若类C继承类B,类B继承类A,则类C既有从类B那里继承下来的属性与方法,也有从类A那里继承下来的属性与方法,还可以有自己新定义的属性和方法。2)继承简化了人们对事物的认识和描述,能清晰体现相关类间的层次结构关系。3)继承提供了软件复用功能。若类B继承类A,那么建立类B时只需要再描述与
2、基类(类A)不同的少量特征(数据成员和成员方法)即可。这种做法能减小代码和数据的冗余度,大大增加程序的重用性。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
3、 void setName(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()
4、return grade;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(姓名:+s
5、tu.getName()+,年龄:+stu.getAge()+学校:+stu.getSchool()+,年级:+stu.getGrade();4.2.1 继承的语法4.2.2 protected访问控制方式 父类和子类是一般类和特殊类关系,子类是需要扩展父类的功能的,在扩展父类的功能时,可能会需要使用到从父类继承的私有成员,但父类的私有成员,在子类中不能直接访问。为此,Java提供了protected访问控制方式来解决这个问题。protected访问控制方式介于private和public之间,用用protected修饰的类里修饰的类里的成员,向所有子类和同一个包的其它类开放其的成员,向所有子
6、类和同一个包的其它类开放其访问权限。访问权限。4.2.3 super关键字与子类对象实例化过程 子类对象实例中这些继承下来的非静态数据成员所占用的内存区域为子类对象实例中的父类子对象。注意父类子对象本身相当于一个父类对象实例。Java 语言的每一语言的每一个对象实例也有一个特殊的私有数据成员,个对象实例也有一个特殊的私有数据成员,称为称为super,用来引用该父类子对象。,用来引用该父类子对象。super 也是一个引用变量,其类型则是它所属的对象实例的父类类型。4.2.3 super关键字与子类对象实例化过程【实例实例4-2】子类对象实例化class Personpublic Person()
7、System.out.println(我是Person类的构造方法);class Student extends Personpublic Student()System.out.println(我是Student类的构造方法);public class SuperDemo1 public static void main(String args)Student stu=new Student();/新建学生对象图4-5 运行结果4.2.3 super关键字与子类对象实例化过程【实例实例4-3】super关键字class Personprivate String name;/姓名private
8、 int age;/年龄public 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)supe
9、r(name,age);/调用父类构造方法,初始化从父类继承的对象属性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
10、.getName()+,年龄:+stu.getAge()+学校:“+stu.getSchool()+,年级:+stu.getGrade();4.2.4 方法重写(Override)方法重写也称为方法覆盖或方法重定义方法重写也称为方法覆盖或方法重定义 class Vehicle public void run()System.out.println(交通工具在跑!);class Truck extends Vehicle Override /表示方法重写的Java注解public void run()System.out.println(货车在地上跑!);class Airplane exten
11、ds Vehicle Override /表示方法重写的Java注解public void run()System.out.println(飞机在天上飞!);4.2.5 final关键字 final在Java中表示最终的意思,使用final可以声明类、属性和方法:1)使用final可以声明常量,常量不能修改,定义时要赋初值;例如:final int NUM=0;2)使用final声明的方法不能被子类重写;3)使用final声明的类不能有子类。4.3 继承与子类型 类A继承类B,则类型A是类型B的子类型。Java语言允许祖先类类型的引用变量指向后代类语言允许祖先类类型的引用变量指向后代类类型的对
12、象。类型的对象。例如,类GraduateStudent是类Student的子类,下述语句是合法的:Student s=new GraduateStudent();类似的如果一个方法的形参是超类类型,那么方法调用时可以传给它一个子类对象作为实参,例如对于一个方法void f(Student d);可以这样来调用它:GraduateStudent s=new GraduateStudent();f(s);/子类对象作为实参4.4 抽象类与多态性 4.4.1 抽象类的引入 抽象类往往用来表征我们在对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。4.4.
13、2 抽象方法 在抽象类中创建的没有具体实现的,必须要子类重写的方法称为抽象方法。抽象方法用关键字abstract进行修饰,这种方法只声明返回的数据类型、方法名称和所需的参数,没有方法体,也就是说抽象方法只需要声明而不需要实现。声明一个抽象方法的基本格式如下:abstract (参数列表);例如:abstract void f();4.4.3 抽象类的定义【实例实例4-4】如何定义抽象类及抽象方法示例abstract class Fruit /定义抽象类public String color;/定义颜色成员变量public Fruit()/定义构造方法color=绿色;/对变量color进行初始
14、化public abstract void harvest();/定义抽象方法class Apple extends Fruit public void harvest()System.out.println(苹果已经收获!);4.4.3 抽象类的定义class Orange extends Fruit public void harvest()System.out.println(桔子已经收获!);public class AbstractClassDemo public static void main(String args)Fruit f1=new Apple();/父类引用指向子类对
15、象f1.harvest();/通过父类引用调用子类对象的重写方法f1=new Orange();f1.harvest();4.4.4 多态性(Polymorphism)“Polymorphism(多态)”一词来自希腊语,意为“多种形式”。指的是一个程序中同名的不同方法共存的情况。多态有编译时(静态)多态和运行时(动态)多态。编译时多态是通过方法重载实现的;运行时多态是通过方法覆盖实现(子类覆盖父类方法)的。4.4.4 多态性(Polymorphism)【实例实例4-5】一个经典的抽象图形类和它的具体子类的例子一个经典的抽象图形类和它的具体子类的例子程序程序4-5 ShapeDemo.javai
16、mport java.util.*;abstract class Shape /Shape类是几个具体图形类的抽象父类 public abstract void draw();/定义抽象方法class Rectangle extends Shape /Rectangle类是Shape类的一个具体子类 Override /表示方法重写的Java注解 public void draw()System.out.println(画矩形);4.4.4 多态性(Polymorphism)class Circle extends Shape /Circle类也是Shape类的一个具体子类 Override
17、public void draw()System.out.println(画圆);class Triangle extends Shape /Triangle类是Shape类的一个具体子类 Override public void draw()System.out.println(画三角形);4.4.4 多态性(Polymorphism)/ShapeDemo类中随机生成矩形、圆、三角形,然后用Shape类型的引用调用 public class ShapeDemo Random rand=new Random();/创建一个随机数类,具体使用可参看Java帮助文档 public Shape cr
18、eateShape()int c=rand.nextInt(3);/产生0-2之间的随机整数 Shape s=null;switch(c)/根据产生的随机整数创建对象 case 0:s=new Rectangle();break;case 1:s=new Circle();break;case 2:s=new Triangle();break;return s;4.4.4 多态性(Polymorphism)public static void main(String args)ShapeDemo demo=new ShapeDemo();Shape shapes=new Shape5;/定义5
19、个Shape类的引用 for(int i=0;ishapes.length;i+)/使5个Shape类的引用指向随机生成的子类对象 shapesi=demo.createShape();for(int i=0;i 100)return new CompanyA();else return new CompanyB();4.11.1 Java接口的实际应用简单工厂设计模式class OrderService /退货处理服务类public void dispatch(Order order)/处理退货单的方法/调用工厂类的静态方法创建退货处理类对象IShippingCourier shipping
20、Courier=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);orderService.dispatch(order1);Ord
21、er order2=new Order(110);orderService.dispatch(order2);4.11.2抽象类的实际应用模版方法设计模式 一、模版方法模式概述一、模版方法模式概述 模板方法(Template Method)模式是一种非常简单而又经常使用的设计模式,先创建一个父类,把其中的一个或多个方法留给子类去实现,这实际上就是在使用模板模式。所谓的模板模式可以这样来理解:在一个类中定义一个算法,但将此算法的某些细节留到子类中去实现。更近一步可以这样来理解:准备一个抽象类,将部分逻辑以具体方法的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类以不同的方法实现
22、这些抽象方法,从而对剩余的逻辑有不同的实现。二、模式意图二、模式意图 将一个类的基本部分抽取出来放到一个基类中,这样它就不必重复出现在几个派生类里。三、模式结构与参与者三、模式结构与参与者 抽象模板角色:1、定义了一个或多个抽象操作,以便让子类实现。2、定义并实现了一个模板方法(指抽象模板类里调用抽象方法和具体方法的方法)。具体模板角色:1、实现父类所定义的一个或多个抽象方法。2、每一个抽象模板角色都可以有任意多个具体模板角色与之对应。3、每一个具体模板角色都可以给出这些抽象方法的不同实现。4.11.2抽象类的实际应用模版方法设计模式 4.11.2抽象类的实际应用模版方法设计模式4.11.2抽
23、象类的实际应用模版方法设计模式 四、实例四、实例电子商务网站的退货处理系统电子商务网站的退货处理系统 退货单目前有两种:无条件退货单和有缺陷退货单。无条件退货允许客户退还商品并接收全额退款,但需要减去最初邮寄和包装的费用,然后将商品添加到库存中。如果客户收到一件有缺陷的商品并希望退货,就形成了有问题的退货,该退款包括最初支付的邮寄和包装的费用,退货后将商品返厂。4.11.2抽象类的实际应用模版方法设计模式 处理退货分为两步,一个是计算退款数量,另一个是退货后处理,这对于两类退货是一样的,但对于两类退货每步具体处理是不一样的。这时,我们可以使用模板方法模式定义一个抽象退货处理类,在其中定义两个抽
24、象方法完成两步处理,再定义一个具体的退货处理方法调用这两个抽象方法(具体实现留给子类去实现)来完成退货处理。定义两个具体退货处理子类,给出父类两个抽象方法的具体实现。实际使用时,根据退货单类型创建具体子类对象,调用从父类继承的退货处理方法来完成退货处理。4.11.2抽象类的实际应用模版方法设计模式4.11.2抽象类的实际应用模版方法设计模式enum ReturnType /退货单类型FaultReturn,/表示有缺陷退货类型NoQuibblesReturn /表示无条件退货类型class ReturnOrder /退货单类 /退货单类型,为了简单,定义成公有成员public ReturnTy
25、pe returnType;/为了简单,其它成员省略4.11.2抽象类的实际应用模版方法设计模式abstract class ReturnProcessTemplate /抽象退货处理类/下面两个是抽象方法,留给子类实现protected abstract void GenerateReturn(ReturnOrder returnOrder);protected abstract void CalculateRefund(ReturnOrder returnOrder);/具体方法,调用两个抽象方法public void process(ReturnOrder returnOrder)Gen
26、erateReturn(returnOrder);CalculateRefund(returnOrder);4.11.2抽象类的实际应用模版方法设计模式/无条件退货处理类class NoQuibblesReturnPross extends ReturnProcessTemplateOverride /表示方法重写的Java注解protected void GenerateReturn(ReturnOrder returnOrder)System.out.println(将商品添加到库存中);/简单示意性代码Overrideprotected void CalculateRefund(Retu
27、rnOrder returnOrder)System.out.println(只退货款);/简单示意性代码4.11.2抽象类的实际应用模版方法设计模式/有缺陷退货处理类class FaultReturnPross extends ReturnProcessTemplateOverrideprotected void GenerateReturn(ReturnOrder returnOrder)System.out.println(将商品返厂);/简单示意性代码Overrideprotected void CalculateRefund(ReturnOrder returnOrder)Syste
28、m.out.println(全额退款);/简单示意性代码4.11.2抽象类的实际应用模版方法设计模式class ReturnProcessFactory /创建退货处理类对象的工厂类/根据退货单类型创建相应的退货处理类对象的静态方法public static ReturnProcessTemplate creatReturnProcess(ReturnType returnType)switch(returnType)case FaultReturn:return new FaultReturnPross();case NoQuibblesReturn:return new NoQuibble
29、sReturnPross();default:return null;4.11.2抽象类的实际应用模版方法设计模式class ReturnService /退货处理服务类public void process(ReturnOrder returnOrder)/处理退货单的方法/调用工厂类的静态方法创建退货处理类对象ReturnProcessTemplate returnProcess=ReturnProcessFactory.creatReturnProcess(returnOrder.returnType);/调用退货处理类对象的方法处理退货 returnProcess.process(re
30、turnOrder);4.11.2抽象类的实际应用模版方法设计模式public class TemplateMethodPatternDemo /应用程序主类 public static void main(String args)ReturnOrder faultReturnOrder=new ReturnOrder();/生成退货单对象 /设置退货单为有缺陷类型 faultReturnOrder.returnType=ReturnType.FaultReturn;/创建退货处理服务类对象 ReturnService returnService=new ReturnService();returnService.process(faultReturnOrder);/调用处理退货单的方法 ReturnOrder noQuibblesReturnOrder=new ReturnOrder();/生成退货单对象 /设置退货单为无条件退货类型 noQuibblesReturnOrder.returnType=ReturnType.NoQuibblesReturn;returnService.process(noQuibblesReturnOrder);/调用处理退货单的方法
侵权处理QQ:3464097650--上传资料QQ:3464097650
【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。