抽象类和接口_第1页
抽象类和接口_第2页
抽象类和接口_第3页
抽象类和接口_第4页
抽象类和接口_第5页
已阅读5页,还剩40页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第1页/共26页,第八章,抽象类和接口,第一单元,第2页/共26页,本章相关学习资源,抽象类和接口专题 阶段练习汽车租赁专题 使用Java实现面向对象编程 第8章 抽象类和接口,学习平台“Java 面向对象”课程,学生用书,第3页/共26页,预习检查,定义抽象类和抽象方法的关键字是什么? abstract 定义接口的语法是什么? public interface 接口名 /接口成员 普通方法和抽象方法的区别 普通方法必须要有方法体,抽象方法不能有方法体(大括号也没有); 抽象方法只能存在于抽象类/接口中,用abstract修饰,访问修饰符不能用private。 抽象类和普通类有什么区别? 抽象

2、类要用abstract修饰;普通类可以实例化,抽象类不能实例化; 抽象类体现的的是一种模板模式的设计。,提问,第4页/共26页,本章任务,模拟实现“愤怒的小鸟”游戏,第5页/共26页,抽象类的定义和使用,理解接口概念,理解面向对象设计原则,理解抽象类和接口的优势,本章目标,接口的定义和使用,点重,理解抽象类概念,点难,点重,第6页/共26页,讲解:为什么使用抽象方法和抽象类,交通工具,实现父类行驶方 法有意义吗?,每个子类有自己独特的行驶方法,交通工具类(抽象类),交通工具类,方法:行驶,抽象方法:行驶,问题:3种交通工具,都有自己的行驶方法,如何设计类结构?,第7页/共26页,串讲:对比普通

3、方法和抽象方法,对比普通方法与抽象方法,public void show() System.out.println(hello); ,public abstract void show();,区别 普通方法必须要有方法体(至少包含一对大括号),抽象方法不能有方法体(大括号也没有) 抽象方法要用abstract修饰,访问修饰符不能用private 抽象方法只能存在于抽象类/接口中,抽象方法定义 非private访问修饰符 abstract 返回值类型 方法名(参数列表) ;,第8页/共26页,串讲:对比普通类和抽象类,对比普通类与抽象类,public class Person Person p

4、= new Person();,public abstract class Person Person p = new Person();,区别 抽象类要用abstract修饰 普通类可以实例化,抽象类不能实例化(即不能使用new创建对象) 抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,否则该子类也是抽象类。,简单的说,抽象类是一个不能实例化的类,它可以具有抽象方法或者普通方法,也可以有构造方法。,代码有没有问题?,第9页/共26页,串讲:抽象类的应用,需求描述 模拟“愤怒的小鸟”游戏中各种鸟的行为,问题,分析 使用抽象类定义鸟类 飞行和叫为抽象类的普通方法

5、攻击为抽象类的抽象方法 在子类中实现攻击方法,演示示例1:抽象类的应用,第10页/共26页,上机练习,需求说明 实现某公司各种岗位(经理、销售人员、普通员工)的员工薪水计算。经理的薪水为基本工资+奖金,销售人员的薪水为基本工资+销售量*每件提成,普通员工只有基本工资; 要求输出不同岗位各一名员工的工资,使用抽象类实现; 分析 定义员工抽象类,具有姓名、基本工资的属性和计算薪水的抽象方法 定义子类:经理类、销售人员类、普通员工类,分别继承员工抽象类,定义各自的属性,重写计算薪水的方法 定义测试类,包含输出员工薪水的静态方法,参数为员工对象(抽象父类的引用指向子类的对象,可以实现多态),完成时间:

6、20分钟,共性问题集中讲解,练习1,第11页/共26页,串讲:抽象类的优势,抽象类可以将已经实现的方法提供给其子类使用,使代码可以被复用,抽象类中的抽象方法在子类中重写,保证了子类还具有自身的独特性,例如:鸟的飞行和叫的方法,不需在子类重复实现,例如:每个鸟都有自己独特的攻击行为,通过抽象类指向其子类的对象,可以实现多态,串讲:抽象类的体现-模板模式Template,编写一个抽象父类,该父类提供了多个子类的通用方法,并把一个或多个抽象方法留给子类去实现,这就是模板设计模式 抽象类是多个具体子类抽象出来的父类,具有高层次的抽象性; 以抽象类作为子类的模板可以避免子类设计的随意性; 抽象类作为多个

7、子类的通用模板,子类在抽象类的基础上进行扩展,但总体上大致保留抽象父类的行为方式; 模板模式应用的简单规则: 抽象父类可以只定义需要使用的某些方法,其余留给子类去实现; 父类提供的方法只是定义了一个通用算法,其具体实现必须依赖子类的辅助;,第13页/共26页,判断对错 抽象类中只能定义抽象方法。 抽象类中不能定义构造方法。 抽象方法可以同时是静态方法。 抽象类中可以没有抽象方法。 声明抽象类和抽象方法都使用abstract关键字。 抽象类不能实例化。 抽象类中可以有静态方法。,小结,提问,第14页/共26页,串讲:理解接口,USB接口其实并不是我们所看到的这些USB插槽,而是这些插槽所遵循的标

8、准规范;我们所看到的插槽只是根据USB规范设计出来的实例而已; 对于不同类型的USB设备而言,他们各自的USB插口都需要遵循同一个规范,遵守这个规范就可以保证插入USB插槽的设备能与主板正常通信; 对于同一块主板上的多个USB插槽,它们有相同的数据交换方式,相同的实现细节,可看作是同一个类的不同实例;,生活中的接口是指某些企业和组织等制定的一种约定或标准 比如USB接口,第15页/共26页,串讲:理解接口,抽象类是从多个类中抽象出来的模板,若要将这种抽象进行得更彻底,就需要用到一种特殊的“抽象类” 接口; Java中的接口提供的也是一种规范,它规定了一个类必须做什么,而不关心这个类到底怎么做。

9、,public interface 接口名 extends 父接口1,父接口2 /抽象方法 ,语法,public 类名 implements 接口 / 实现接口定义的方法 / 普通方法 ,演示示例2:使用接口描述USB,注意,接口没有构造方法,不能实例化; 接口只能继承接口,不能继承类; 接口里没有普通方法,都是抽象方法,默认修饰符是public abstract; 接口里的字段都是全局常量,默认修饰符是public static final;,一个类如果要实现一个接口,则必须实现该接口定义中的所有方法,否则该类只能定义为抽象类,通常在接口名前加上字母I,用于区分类和接口,同时用static和

10、final修饰的域(即编译器常量)使用大写字母表示,每个单词用下划线隔开,串讲:final关键字,根据上下文环境,final关键字存在着细微的区别,但通常指的是“这是无法改变的”。 final可以修饰类,方法,变量。 final修饰的类不可以被继承。 final修饰的方法不可以被重写。 final修饰的变量是一个常量。只能被赋值一次。 对基本类型,使用fianl,不能改变的是它的数值; 对引用类型,使用fianl,不能改变的是它的引用,而对象本身是可以修改的。一旦一个final引用被初始化指向一个对象,这个引用将不能在指向其他对象; 对于static final修饰的全局常量,必须在声明的同时

11、赋初值;,第17页/共26页,串讲:对比抽象类和接口,对比抽象类与接口,public abstract class Person /抽象方法 /普通方法 ,public interface Person /抽象方法 ,区别 抽象类使用abstract声明,接口使用interface声明 抽象类可以包含属性、抽象方法(必须使用abstract关键字)、普通方法和构造方法,也可以不含抽象方法 接口只能包含抽象方法(无须使用abstract关键字)和常量,接口和抽象类一样,不能实例化,抽象类与接口有什么区别?,提问,第18页/共26页,讲解:认识抽象类的局限性,实现“愤怒的小鸟”游戏中鸟叫的行为,代

12、码冗余,复用度差,第19页/共26页,讲解:使用接口优化程序设计,将鸟叫的行为定义为接口 实现鸟叫接口输出各种具体的鸟叫声 将鸟叫行为作为抽象鸟类的一个属性,能不能用接口来实现鸟叫的行为,从而既避免代码冗余,又不影响扩展性?,问题,分析,演示示例3:使用接口优化程序设计,接口规定了实现类里必须提供的方法,体现了规范和实现的分离,增强了系统的扩展性和可维护性;,第20页/共26页,上机练习,需求说明 电视、风扇、冰箱等各种电器要想工作必须提供电源,使用接口模拟电器获得电源后进行工作 分析 定义电源的接口,具有供电的方法 定义类:电视、风扇和冰箱类,分别实现电源接口 定义测试类,包含电器开始工作的

13、方法,参数为电器对象(接口的引用指向实现类的对象,可以实现多态),完成时间:20分钟,共性问题集中讲解,练习2,/* 手机工厂 */ class PhoneFactory public static ICellPhone getInstance(String type) ICellPhone p = null; if (samsung.equalsIgnoreCase(type) p = new SAMSUNG(); else if (iphone.equalsIgnoreCase(type) p = new IPhone(); return p; public static void mai

14、n(String args) /ICellPhone p = new SAMSUNG(); ICellPhone p = PhoneFactory.getInstance(samsung); p.sendMsg(); ,串讲:简单工厂模式SimpleFactory,/手机标准 interface ICellPhone void sendMsg(); ,/* 三星手机 */ class SAMSUNG implements ICellPhone public void sendMsg() /* IPhone手机 */ class IPhone implements ICellPhone publ

15、ic void sendMsg() ,屏蔽不同子类实现的差异,提高代码的可扩展性和可维护性,第22页/共26页,串讲:实现多个接口,一个类只能继承一个父类,但能同时实现多个接口。,class 类名 extends 父类名 implements 接口1,接口2, /类的成员 ,语法,一个类可以同时继承类和实现接口,但是extends必须位于implements之前,一个类实现多个接口,必须实现每个接口中的方法,否则只能定义为抽象类,接口可以继承接口吗?如果可以,能继承多个吗? 接口可以实现接口吗? 接口可以继承一个或多个接口;接口不能实现接口。,提问,第23页/共26页,串讲:实现多个接口,示例

16、,某人既是软件工程师,又是慈善家,该如何实现?,分析,定义人类作为抽象父类,包含人的基本属性和行为 定义编程接口,拥有编程能力 定义慈善接口,拥有做慈善能力 定义一个子类,继承人类,同时实现编程接口和慈善接口,演示示例4:实现多个接口,第24页/共26页,上机练习,需求说明 在职研究生既要学习,还要工作,使用实现多个接口的方式定义研究生类 分析 定义人类作为抽象父类,包含人的基本属性和行为 定义学习接口,拥有学习能力 定义工作接口,拥有工作能力 定义研究生类,继承人类,同时实现学习接口和工作接口,完成时间:20分钟,共性问题集中讲解,练习3,第25页/共26页,小结:接口,Java中的接口提供

17、了一种规范,规定一个类必须做什么, 使得所有实现该接口的类在形式上都能保持一致; 接口里的成员包括(主要是前两个): 全局常量 公共的抽象方法 内部类(包括内部类,内部接口,内部枚举类); 接口不能创建实例,但是可以用来声明引用类型变量。 此时,引用类型的变量必须指向其实现类的对象。 例:IStudent s = new StudentImpl();,小结:接口和抽象类,相同点: 都位于继承的顶端,用于被其他类实现或继承; 自身不能实例化,都是依靠对象多态性,通过实现类/子类进行对象实例化; 都可以包含抽象方法,其实现类/子类都必须重写这些抽象方法; 区别: 抽象类中可以含有成员变量,接口中只

18、有全局常量; 抽象类可以含有构造方法,可以为部分方法提供实现,避免子类重复实现这些方法,提高代码的重用性;接口只能包含抽象方法; 一个类只能继承一个直接父类(可以是抽象类),却可以实现多个接口;(接口弥补了Java单继承的局限) 二者的选用: 优先使用接口,尽量避免使用抽象类; 需要定义子类的行为,又要为子类提供共性功能时才考虑选用抽象类;,串讲:适配器模式Adapter,有一个现成的类/接口,但是它不完全符合你的需求,咋办? 比如窗体有变大、变小、关闭的行为,但是我现在只需要关闭行为;,interface IWindow void max(); void min(); void close(

19、); ,abstract class WindowAdapter implements IWindow public void max() public void min() public void close() class MyWindow extends WindowAdapter public void close() System.out.print(自己关闭窗口); ,默认适配器模式:在接口和具体实现类之间添加一个抽象类,用抽象类去空实现目标接口的所有方法,具体的实现类只需要覆盖其需要完成的方法即可。,适配器模式的其他用法可参考: ,第28页/共26页,小结:抽象类与接口,第29页

20、/共26页,串讲:面向对象,什么是面向对象 对象是人们要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象。它不仅能表示具体的事物,还能表示抽象的规则、计划或事件(回忆:面向对象三大特性?) 对象具有状态,一个对象用数据值来描述它的状态。 对象还有操作,用于改变对象的状态。 对象实现了数据和操作的结合,将数据和操作封装于其中 面向对象(Object Oriented,简称OO)就是将现实世界的事物抽象成对象,现实世界中的关系抽象成类、继承,帮助人们实现现实世界转换成系统模型的一种软件开发方法。,串讲:面向对象,面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程 强调

21、的是功能行为 面向对象 将功能封装进对象,强调的是具备了功能的对象。 面向对象是基于面向过程的。,串讲:面向对象的特点,是一种符合人们思考习惯的思想 可以将复杂的事情简单化 将程序员从执行者转换成了指挥者 完成需求时: 先要去找具有所需的功能的对象来用。 如果该对象不存在,那么创建一个具有所需功能的对象。 这样简化开发并提高复用。,串讲:面向对象分析、设计、编程,面向对象分析(OOA,Object Oriented Analysis) 其实就是找出对象之间的关系。 UML(Unified Modeling Language,统一建模语言)是面向对象技术领域内占主导地位的标准建模语言 面向对象设

22、计(OOD,Object Oriented Design) 其实就是在管理和维护对象之间的关系。 面向对象编程(OOP,Object Oriented Programming) 其实就是不断的创建对象,使用对象,指挥对象做事情。,第33页/共26页,串讲:面向对象的设计原则,开放封闭原则 Open-Closed Principle,OCP 里氏代换原则 Liskov Substitution Principle,LSP 依赖倒转原则 Dependence Inversion Principle,DIP 合成/聚合复用原则 Composite/Aggregate Reuse Principle,

23、CARP 迪米特法则 Law of Demeter,LoD 接口隔离原则 Interface Segregation Principle,ISP 单一职责原则 Single Responsibility Principle,SRP,面向对象设计的基石,手段和工具,第34页/共26页,串讲:面向对象的设计原则,开放封闭原则(简称开-闭原则) 定义:一个软件实体如类、模块和函数应该先用抽象构建框架,再用实现扩展细节。即对扩展开放,对修改关闭。 问题由来:在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且

24、需要重新测试原有代码。 解决方案:当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。 在面向对象编程中,通过抽象类及接口,规定了具体类的特征作为抽象层,相对稳定,不需更改,从而满足“对修改关闭”;而从抽象类导出的具体类可以改变系统的行为,从而满足“对扩展开放”。,第35页/共26页,串讲:面向对象的设计原则,里氏代换原则(亦称里氏替换) 定义:所有引用基类的地方必须能透明地使用其子类的对象。 问题由来:有一功能P1,由类A完成。现需要将功能P1进行扩展,扩展后的功能为P,其中P由原有功能P1与新功能P2组成。新功能P由类A的子类B来完成,则子类B在完成

25、新功能P2的同时,有可能会导致原有功能P1发生故障。 解决方案:类B继承类A时,除添加新的方法完成新增功能P2外,尽量不要重写父类A的方法,也尽量不要重载父类A的方法。 里氏替换原则通俗的来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。它包含以下3层含义: 子类可以重写父类的抽象方法,但不能重写父类的非抽象方法。 子类中可以增加自己特有的方法。 当子类的方法实现父类的抽象方法时,方法的返回值类型要比父类更严格。,第36页/共26页,串讲:面向对象的设计原则,依赖倒转原则(亦称依赖倒置) 定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。即

26、针对接口编程,不依赖于具体实现。 问题由来:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成。这种场景下,类A一般是高层模块,负责复杂的业务逻辑;类B和类C是低层模块,负责基本的原子操作;假如修改类A,会给程序带来不必要的风险。 解决方案:将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I间接与类B或者类C发生联系,则会大大降低修改类A的几率。 在实际编程中,我们一般需要做到如下3点: 底层模块尽量都要有抽象类或接口,或者两者都有。 变量的声明类型尽量是抽象类或接口。 使用继承时遵循里氏替换原则。,第37页/共26页,串讲:面向对象的设计原则,合成/聚合

27、复用原则 定义:在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象的委派达到复用这些对象的目的。 问题由来:为了代码复用而滥用继承会增加系统构建、维护时的难度及系统的复杂度。 解决方案:如果两个类是“Has-a”关系应使用合成、聚合,如果是“Is-a”关系可使用继承。“Is-A”是严格的分类学意义上定义,意思是一个类是另一个类的“一种”。而“Has-A”则不同,它表示某一个角色具有某一项功能或组成部分。 聚合(Aggregation)表示整体和部分的关系,表示“拥有”。如奥迪A6汽车,对奥迪A6引擎、奥迪A6轮胎的关系是聚合关系,离开了奥迪A6汽车,引擎、轮胎

28、也可以单独存在。 合成(Composition)则是一种更强的“拥有”,部分和整体的生命周期一样。合成的新的对象完全支配其组成部分,包括它们的创建和湮灭等。比如人和人的大脑。,第38页/共26页,串讲:面向对象的设计原则,迪米特法则(亦称最少知识原则,Least Knowledge Principle,LKP) 定义:一个对象应该对其他对象保持最少的了解。也就是说,陌生的类最好不要作为局部变量的形式出现在类的内部。 问题由来:类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。 解决方案:尽量降低类与类之间的耦合。 可以通俗的理解为不跟“陌生人”说话,只与直接的朋友

29、通信。 每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系(依赖、关联、组合、聚合等),我们就说这两个对象之间是朋友关系。 其中,我们称出现成员变量、方法参数、方法返回值中的类为直接的朋友,而出现在局部变量中的类则不是直接的朋友。 迪米特法则在运用到系统设计中应注意以下几点: 每个类都应当尽量良好封装。 一个类对其它类的引用应该降到最低,尽量避免在局部变量中引入陌生类。,第39页/共26页,串讲:面向对象的设计原则,接口隔离原则 定义:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。 问题由来:类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对

30、于类A和类B来说不是最小接口,则类B和类D必须去实现他们不需要的方法。 解决方案:将臃肿的接口I拆分为独立的几个接口,类A和类C分别与他们需要的接口建立依赖关系。 采用接口隔离原则对接口进行约束时,要注意以下几点: 接口尽量小,但是要有限度。对接口进行细化可以提高程序设计灵活性是不争的事实,但是如果过小,则会造成接口数量过多,使设计复杂化。 为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系。 提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。,第40页/共26页,串讲:面向对象的设计原则,单一职责原则 定义:不要存在多于一个导致类变更的原因

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论