1、Java编程精要 Java接口技术福建 厦门2016年6月本章目标本章目标n掌握Java接口n理解Java接口与多态的关系n掌握面向接口编程的思想n掌握常量接口的使用本章相关词汇本章相关词汇单单 词词说说 明明interface接口,界面接口,界面implements实现实现final最终的,决定性的最终的,决定性的生活中的接口n电脑主板上的PCI插槽的规范就类似于Java接口 每种卡的内部结构都不相同,可以把每种卡的内部结构都不相同,可以把声卡、网卡、显卡都插在声卡、网卡、显卡都插在PCI插槽上,插槽上,而不用担心哪个插槽是专门插哪个卡而不用担心哪个插槽是专门插哪个卡的的声卡声卡显卡显卡网卡
2、网卡主板主板Java中的接口 n一个Java接口是一些方法特征的集合,但没有方法的实现public interface PCI public void start();public void stop();这是这是Java接口,相当接口,相当于主板上的于主板上的PCI插槽的插槽的规范规范Java中的接口 class SoundCard implements PCI public void start()System.out.println(Du du.);public void stop()System.out.println(Sound stop!);Java接口中定义的方法在不同的地方被实
3、现,可以接口中定义的方法在不同的地方被实现,可以具有完全不同的行为具有完全不同的行为声卡、网卡都实现了声卡、网卡都实现了PCI插槽的规范,但行为完全不同插槽的规范,但行为完全不同 Java中的接口 class NetworkCard implements PCI public void start()System.out.println(Send.);public void stop()System.out.println(Network stop!);声卡、网卡都实现了声卡、网卡都实现了PCI插槽的规范,但行为完全不同插槽的规范,但行为完全不同 public class Assembler
4、public static void main(String args)PCI nc=new NetworkCard();PCI sc=new SoundCard();nc.start();sc.start();Java接口可以用于定义数据接口可以用于定义数据运行时,根据实际创建的对象类型调用相应的方运行时,根据实际创建的对象类型调用相应的方法实现法实现Du du.Send.控制台输出控制台输出Java中的接口 n为各学校开发这样一个小系统,包含类型:教员、学校、打印机,具体要求如下:教员、以及学校都具有方法:返回详细信息学校具有方法:打印,能够通过学校的打印机打印教员或学校的详细信息系统要具
5、备良好的可扩展性与可维护性打印打印 教员教员 学校学校 教员教员详细信息详细信息学校学校详细信息详细信息detail方法方法(输出详细信息)(输出详细信息)Java中的接口 n假设一个系统中包含三个类:教师(Teacher)、学校(School)、打印机(Printer),具有如下要求:教员和学校都具有方法tell,用于返回信息打印机能够将学校或教员返回的信息输出Java中的接口 打印打印 教员教员 学校学校 教员教员信息信息学校学校信息信息tell方法方法public class Teacher public String tell()return 本人是教员本人是教员;public cla
6、ss School public String tell()return 这里是学校这里是学校;public class Printer public void print(Teacher t)System.out.println(t.tell);public void print(School s)System.out.println(s.tell);每增加一种新类型,每增加一种新类型,都需要增加相应的都需要增加相应的print(类型名称类型名称 var)方法方法n可以使用多态来解决这个问题吗?可以使用多态来解决这个问题吗?教员教员 学校学校 tell方法方法教员教员信息信息学校学校信息信息
7、1221两个类具有同名方法,但具体实现不同,应根据具体的实例决定使用哪个tell方法满足使用多态的条件,但教员与学校两个类不存在共性,不适合由同一个基类派生教员、学校都存在一个共同的方法tell,它们对该方法有各自不同的实现这完全符合Java接口的定义定义一个定义一个Java接口,在接口,在其中定义其中定义tell方法,但没方法,但没有具体实现有具体实现实现这个实现这个Java接口,不接口,不同的类对同的类对tell方法有不同方法有不同的具体实现的具体实现IntroduceableTeacher(教员教员)School(学校学校)public class Teacher implements
8、Introduceablepublic String tell()return 本人是教员本人是教员;public class School implements Introduceable public String tell()return 这里是学校这里是学校;public interface Introduceable public String tell();public class Printer public void print(Introduceable intro)System.out.println(intro.tell);n使用print方法时,参数可以是任何Intro
9、duceable接口的实现类的对象,不必再为不同的类型建立不同的print方法了n通过Java接口,我们同样可以享受到多态性的好处,大大提高了程序的可扩展性及可维护性nJava接口允许多重实现(即一个类同时实现多个接口)编程练习n为刚才完成的系统增加一种新的类型:学员(Student),具体要求如下:学员具有tell方法,负责输出学员信息能够通过学校的打印机打印学员的信息n编写测试类进行测试面向接口编程n开发系统时,主体构架使用接口,接口构成系统的骨架n这样就可以通过更换接口的实现类来更换系统的实现IntroduceableTeacher(教员教员)School(学校学校)面向接口编程 升级上
10、述的系统,要求:打印机有多种类型,比如:黑白打印机、彩色打印机等 学校可能配备其中任意一款打印机,负责打印学校的详细信息print方法方法(打印)(打印)彩色打印机彩色打印机 黑白打印机黑白打印机 黑白内容黑白内容学校学校/教员教员 详细信息详细信息 彩色内容彩色内容抽象出Java接口(1)分析:黑白、彩色打印机都存在一个共同的方法特征print;黑白、彩色打印机对print方法有各自不同的实现(2)结论:抽象出Java接口PrinterInf,在其中定义方法print(3)具体实现:public interface PrinterInf public void print(String co
11、ntent);面向接口编程实现Java接口(1)分析:已经抽象出Java接口PrinterInf,并在其中定义了print方法黑白、彩色打印机对print方法有各自不同的实现(2)结论:黑白、彩色打印机都实现PrinterInf接口,各自实现print方法(3)具体实现:面向接口编程public class ColorPrinter implements PrinterInf public void print(String content)System.out.println(彩色打印:彩色打印:);System.out.println(content);public class Black
12、Printer implements PrinterInf public void print(String content)System.out.println(黑白打印:黑白打印:);System.out.println(content);使用Java接口更换实现接口的类就可以更换系统的实现面向接口编程public class School private PrinterInf printer;/打印机打印机 public void setPrinter(PrinterInf p)this.printer=p;public void print()printer.print(厦门理工学院厦
13、门理工学院);面向接口编程public class Test public static void main(String args)/创建学校实例创建学校实例 School school=new School();/为该学校配备黑白打印机为该学校配备黑白打印机 school.setPrinter(new BlackPrinter();school.print(school);/为该学校配备彩色打印机为该学校配备彩色打印机 school.setPrinter(new ColorPrinter();school.print(school);代码阅读阅读如下Java代码,然后请采用面向接口编程的思
14、想,在空白处填写正确的代码public interface PCI void start();void stop();class SoundCard implements PCI public void start()System.out.println(Du du.);public void stop()System.out.println(Sound stop!);class NetworkCard implements PCI public void start()System.out.println(Send.);public void stop()System.out.println
15、(Network stop!);这是这是Java接口,相当于主接口,相当于主板上的板上的PCI插槽的规范插槽的规范声卡、网卡都实现了声卡、网卡都实现了PCI插槽的规范,但行为完全不同插槽的规范,但行为完全不同public class MainBoard public void usePCICard(_ p)p.start();p.stop();public class Assembler public static void main(String args)MainBoard mb=new MainBoard();/在主板上插入网卡在主板上插入网卡 /在主板上插入声卡在主板上插入声卡 提示:
16、通过这个方法,主板上提示:通过这个方法,主板上可以插入任意符合可以插入任意符合PCI插槽规插槽规范的卡范的卡PCI nc=new NetworkCard();mb.usePCICard(nc);PCI sc=new SoundCard();mb.usePCICard(sc);PCI提示:可以通过更换实现接口的类提示:可以通过更换实现接口的类来更换系统的实现来更换系统的实现代码阅读常量概述n生活中,一周有七天,如何用代码表示?public class Week private int days=7;public static void main(String args)Week w=new We
17、ek();System.out.println(一周有一周有+w.days+天天);public class Week private int days=7;public static void main(String args)Week w=new Week();w.days+;System.out.println(一周有一周有+w.days+天天);一周有一周有7天天控制台输出控制台输出 然而,总有不尽人意的事情发生:一周有一周有8天天控制台输出控制台输出如何保证变量的值在运行期无法被改变?如何保证变量的值在运行期无法被改变?使用常量使用常量 n常量是一种标识符,它的值在运行期间恒定不变n
18、常量标识符在程序中只能被引用,而不能被重新赋值常量常量圆周率圆周率PI圆周率圆周率PI代码表示代码表示方式方式public static final double PI=3.14159265358979323846;用法用法将将ang角度转换成径度角度转换成径度 public static double toRadians(double ang)return ang/180.0*PI;常量概述n如果不使用常量,直接在程序中填写数字或字符串,将会有什么麻烦?public static double toRadians(double ang)return ang/180.0*3.141592653
19、58979323846;public static double toDegrees(double ang)return ang*180.0/3.14159265358979323846;public static final double PI=3.14159265358979323846;/圆周率圆周率public static double toRadians(double ang)return ang/180.0*PI;public static double toDegrees(double ang)return ang*180.0/PI;程序的可读性变差:用程序的可读性变差:用户很
20、难理解数字或字符户很难理解数字或字符串的意思串的意思程序的可维护性变差:如程序的可维护性变差:如果数值改变,则需要在很果数值改变,则需要在很多地方改动,既麻烦又易多地方改动,既麻烦又易出错出错使用常量可以增强程序的可读性、可维护性使用常量可以增强程序的可读性、可维护性常量概述Java中常量的定义规则n加入final关键字代表常量,再加入static关键字代表类常量n尽量使用含义直观的常量名(大写)来表示那些将在程序中多次出现的数字或字符串public class Student public static final int FEMALE=1;/代表女性代表女性public static fi
21、nal int MALE=2;/代表男性代表男性private int sex;/性别性别public void setSex(int sex)if(sex=FEMALE)System.out.println(这是一名女学生这是一名女学生);else if(sex=MALE)System.out.println(这是一名男学生这是一名男学生);this.sex=sex;在接口中声明常量n在Java 接口中声明的变量在编译时会自动加上static final的修饰符,即声明为常量,因为Java接口只允许出现类常量(静态常量)public interface SchoolType public s
22、tatic final String SCHOOL =“厦门理工学院厦门理工学院;public interface SchoolType String SCHOOL =“厦门理工学院厦门理工学院;等同于等同于OOP思想总结OOP基基本特征本特征定义定义具体实现方式具体实现方式优势优势封装封装隐藏实现细节,对外提供隐藏实现细节,对外提供公共的访问接口公共的访问接口属性私有化、添加公有的属性私有化、添加公有的setter、getter方法方法增强代码的可维增强代码的可维护性护性,数据的安全数据的安全性性继承继承从一个已有的类派生出新从一个已有的类派生出新的类,子类具有父类的一的类,子类具有父类的一
23、般特性,以及自身特殊的般特性,以及自身特殊的特性特性继承需要符合的关系:继承需要符合的关系:is-a,通过使用通过使用extends关键字实关键字实现继承,使用现继承,使用super调用父调用父类的成员类的成员1、实现抽象、实现抽象(抽出像的部分)(抽出像的部分)2、增强代码的、增强代码的可复用性可复用性多态多态同一个实现接口,使用不同一个实现接口,使用不同的实例而执行不同操作同的实例而执行不同操作通过通过Java接口接口/继承来定义继承来定义统一的实现接口;通过方法统一的实现接口;通过方法重写为不同的实现类重写为不同的实现类/子类子类定义不同的操作定义不同的操作增强代码的可扩增强代码的可扩展
24、性、可维护性展性、可维护性代码阅读public interface Introduceable public String detail();public void introduction()detail();private void showMessage();void speak();Java接口中的方法必须是接口中的方法必须是publicJava接口中不能有方法体实现接口中不能有方法体实现 编译器会自动加上编译器会自动加上public修饰符修饰符请指出下列Java代码中的错误工厂设计模式工厂设计模式n工厂设计模式也是最常用的设计模式之一n它的核心思想是通过专门定义一个类,来负责创建其他
25、类的实例n被创建的实例通常都具有共同的父类工厂设计模式工厂设计模式public interface Fruit public void eat();class Apple implements Fruit public void eat()System.out.println(“吃苹果吃苹果”);class Orange implements Fruit public void eat()System.out.println(“吃橘子吃橘子”);工厂设计模式工厂设计模式public class EatDemo public static void main(String args)Fruit
26、f=new Apple();f.eat();当要吃其它类型的水果时,就要修改代码有缺陷吗?工厂设计模式工厂设计模式工厂设计模式工厂设计模式public interface Fruit public void eat();class Apple implements Fruit public void eat()System.out.println(“吃苹果吃苹果”);class Orange implements Fruit public void eat()System.out.println(“吃橘子吃橘子”);工厂设计模式工厂设计模式Class Factory public static
27、 Fruit getInst(int arg)Fruit f;if(arg=1)f=new Apple();if(arg=2)f=new Orange();return f;工厂设计模式工厂设计模式public class EatDemo public static void main(String args)Fruit f;Scanner input=new Scanner(System.in);int arg=input.nextInt();f=Factory.getInst(arg);input.close();f.eat();开发任务开发需求开发需求(1)信用卡分为)信用卡分为VISA
28、,AMERICANEXPRESS,MASTERCARD三种类型,为每种信用卡写一个类三种类型,为每种信用卡写一个类(2)每个信用卡类都有一个处理)每个信用卡类都有一个处理POS机刷卡的方法机刷卡的方法swipeCard_POS()(3)请使用接口技术和工厂模式实现开发需求)请使用接口技术和工厂模式实现开发需求适配器设计模式适配器设计模式nJava要求实现接口的类必须覆写接口中的所有抽象类n当一个接口中定义了大量的抽象方法,而实现该接口的子类只需要其中的一部分时,会产生麻烦n适配器设计模式的思想是通过设置一个中间类(适配器类)来实现接口的所有方法,但方法体为空(虚假实现);从而,子类可以有选择的
29、覆写其所需的方法n适配器类通常不应该被直接使用,因此应定义为抽象类适配器设计模式适配器设计模式适配器设计模式适配器设计模式n例如某种操作系统中的标准窗口包含打开、关闭、移动、最小化和最大化等五个操作;而在开发某个软件时,其窗口只需要打开和关闭这两个操作;此时,可通过设计适配器来虚假实现标准窗口的全部操作,而真实的窗口只需继承适配器,并实现所需的两个操作即可适配器设计模式适配器设计模式/标准窗口标准窗口interface Window public void open();public void close();public void move();public void iconified()
30、;/最小化最小化 public void deiconified();/最大化最大化适配器设计模式适配器设计模式/适配器类实现标准窗口,虚假实现所有抽象方法适配器类实现标准窗口,虚假实现所有抽象方法abstract class WinAdapter implements Window abstract public void open();abstract public void close();public void move();public void iconified();public void deiconified();适配器设计模式适配器设计模式/具体类继承适配器类,实现所需方法
31、具体类继承适配器类,实现所需方法class MyWindow extends WinAdapter public void open()System.out.println(“窗口打开窗口打开”);public void close()System.out.println(“窗口关闭窗口关闭”);开发任务开发需求开发需求(1)编写与定位技术有关的接口)编写与定位技术有关的接口Location,其中包,其中包含与三种定位技术有关的抽象方法:含与三种定位技术有关的抽象方法:GPS、LBS与与DBS(2)分别为每种方法编写适配器类(抽象类),并)分别为每种方法编写适配器类(抽象类),并编写相应的具体
32、类编写相应的具体类对象排序对象排序n创建一个学生类创建一个学生类Student,拥有以下属性与方法:,拥有以下属性与方法:属性:学号、姓名、性别、身高、体重属性:学号、姓名、性别、身高、体重方法:输出学生信息方法:输出学生信息n创建一个班级类创建一个班级类Class,拥有以下属性与方法:拥有以下属性与方法:属性:班级名、班级学生属性:班级名、班级学生方法:输出所属学生信息方法:输出所属学生信息n编写方法编写方法sortStu(),按身高从小到大对班级内的学,按身高从小到大对班级内的学生进行排序生进行排序ComparableComparable与与ComparatorComparator接口接口
33、n若一个类实现了若一个类实现了Comparable接口,并重写了其中接口,并重写了其中compareTo()方法,则该类的对象就成为了可比较对方法,则该类的对象就成为了可比较对象象ComparableComparable与与ComparatorComparator接口接口public class Student implements Comparable.public int compareTo(Student o)if(this.height o.height)return 1;if(this.height o.height)return-1;return 0;ComparableCompa
34、rable与与ComparatorComparator接口接口n若一个类实现了若一个类实现了Comparable接口,并重写了其中接口,并重写了其中compareTo()方法,则该类的对象就成为了可比较对方法,则该类的对象就成为了可比较对象象n可以直接利用可以直接利用Collections.sort(list)对多个该类的对象对多个该类的对象进行排序进行排序Collections.sort(students)ComparableComparable与与ComparatorComparator接口接口n但是,如果需要依据不同属性进行排序应该如何处但是,如果需要依据不同属性进行排序应该如何处理理n
35、例如,要提供按照体重与学号排序(从小到大)的例如,要提供按照体重与学号排序(从小到大)的两个方法,应该如何实现两个方法,应该如何实现ComparableComparable与与ComparatorComparator接口接口public class WeightComparator implements Comparator public int compare(Student arg0,Student arg1)if(arg0.weight arg1.weight)return-7;return 0;ComparableComparable与与ComparatorComparator接口接口
36、n可以使用可以使用Collections.sort(list,comparator)方进行排方进行排序序Collections.sort(students,new WeightComparator()开发需求开发需求n编写货币基金类,拥有以下属性与方法:编写货币基金类,拥有以下属性与方法:属性:基金编号,基金名称,万份收益,七日属性:基金编号,基金名称,万份收益,七日年化收益年化收益方法:输出货币基金信息方法:输出货币基金信息n创建货币基金市场创建货币基金市场MoneyFundMarket类,拥有以类,拥有以下属性与方法:下属性与方法:属性:名称、货币基金列表属性:名称、货币基金列表方法:输出所有货币基金信、将基金按七日年方法:输出所有货币基金信、将基金按七日年化收益率从高到低排序、将基金按万份收益从化收益率从高到低排序、将基金按万份收益从高到低排序、将基金按高到低排序、将基金按ID从小到大排序(字典从小到大排序(字典顺序)顺序)开发任务