• 1. 第七章 接口
  • 2. 7.1 接口举例 7.2 接口的说明 7.3 扩展接口 7.4 接口的使用 7.5 何时使用接口 7.6 小结第七章 类的扩展
  • 3. 什么是接口 接口:由抽象方法和常量构成的类型。以表示一组类所提供的一组相关服务。类和接口都是 一种类型。 接口的特征 接口纯从设计着眼,不包括实现; 类不仅要设计,还要加以实现。第七章 接口interface Instrument { int i = 5; // public static final void play( ); // public abstract String what( ); // public abstract void adjust( ); // pubic abstract }
  • 4. 多继承:接口提供了Java的多重继承功能。 对于一个类:所扩展的类和所实现的接口均称为“超类型”(supertype)。而自己作为“子类型”(subtype)。 Java多继承的本质:只继承约定,而不继承实现。 新类的对象的引用可用在任何对超类型(类或接口)对象引用的地方。第七章 接口类1接口1类2接口2extends implements超类型Class1 c1 = new Class1( ); Class2 c2 = new Class2( ); Interface1 i1;getItem(Class1 item); getItem(Interface1 item); getItem(c2);子类型
  • 5. Comparable接口7.1 接口举例//对象间比较大小 public interface Comparable{ int compareTo(Object o); } //以某一个天体为中心环绕的多个天体间,各自距中心的轨道距离比较(水星<金星<地球) class Body implements Comparable{ //body fields omitted int orbitalDistance = …//set during construction public int compareTo(Object o){ Body other = (Body)o; if (orbits == other.orbits) return orbitalDistance – other.orbitalDistance; else throw new IllegalArgumentException("bad orbit"); } } 注意:实现接口的类必须实现接口中的所有方法; 如果仅实现接口中的部分方法,该类必须被说明为抽象的。
  • 6. 接口的优势是用于说明和使用接口类型的变量。7.1 接口举例//通用的排序类 class Sorter{ public static Comparable[] sort(Comparable[] list){ //无需考虑具体排序对象的类型 //implementation details return list; } }通过接口类型的引用只能访问接口的成员。Comparable obj = new Body(); String name = obj.getName(); //INVALID: Comparable has no getName method接口类型的引用隐含地可作为Object类型的引用。String desc = obj.toString(); //正确的
  • 7. 接口可说明三种类型的成员(所有成员都隐含为public) 常量(域) 方法 内嵌类和接口 接口常量 接口方法 接口修饰符 public:该接口可公共访问; abstract:所有接口隐含为抽象的,所以可省略; strictfp:该接口说明的所有float和double表达式均按严格浮点数计算。7.2 接口的说明 interface Verbose { int SILENT = 0; int TERSE = 1; int NORMAL = 2; int VERBOSE = 3; void setVerbosity(int level); int getVerbosity(); }public abstractpublic static final
  • 8. 使用extends关键字扩展接口。可同时扩展多个接口。 扩展接口中包含被扩展接口的所有方法和常量。 可将一个接口类型的表达式传给一个具有Object类型引用的方法7.3 扩展接口WXYZinterface W{ }; interface X extends W{ }; class Y implements W{ }; class Z extends Y implements X{ };WXZYinterface W{ }; interface X extends W{ }; interface Y extends W{ }; class Z implements X,Y{ };protected void twiddle (W wRef){ Object obj = wRef; //... }接口类型表达式表示的对象肯定 属于某个类,而所有类都是根类 Object的子类。
  • 9. 在继承中,若常量名相同,则使用受限的名来访问。7.3.1 继承和隐藏常量Interface PokerDeck DECK_SIZEInterface TarotDeck DECK_SIZEInterface ( or class ) MultiDeck PokerDeck.DECK_SIZE; TarotDeck.DECK_SIZE;多重继承Interface PokerDeck DECK_SIZEInterface ( or class ) MultiDeck PokerDeck.DECK_SIZE; DECK_SIZE;//新定义的添加新常量
  • 10. 类型层次较深,通过显式类型转换访问隐藏常量。7.3.1 继承和隐藏常量Interface X int val =1;Interface Y int val = 2; int sum=0;class ZZ z = new Z(); System.out.println("z.val=" + z.val + z.sum + ", ((Y)z).val = " + ((Y)z).val + ", ((X)z).val = " + ((X)z).val);z.val=20, ((Y)z).val = 2, ((X)z).val = 1
  • 11. 在多重继承中,当相同名字的方法出现在多个接口时(基调指方法的 名以及形参的数目和类型): 方法名相同,但含有不同数目或不同类型的参数子接口有两个名复用的方法,它们有相同的名字和不同的基调。基调完全相同子接口有一个此基调的方法两方法仅返回类型不同。两个超接口不能同时实现。两个方法仅引发的异常类型不同用唯一的实现满足这两种引发的异常类型。7.3.2 继承、改写和名复用XYZinterface X { void setup() throws SomeException; } interface Y { void setup(); } class Z implements X,Y { public void setup() { //... } }
  • 12. 实现接口的类是否有非静态域,是否有静态方法。 一个类实现了某个接口,那么该类是否实现了它的所有超接口。 一个类实现了某个接口,那么是否该类的所有子类也实现了此接口。问 题
  • 13. 7.4 接口的使用class Body{ private long idNum; public String name = ""; private Body orbits = null; private static long nextID = 0; Body(){ idNum = nextID++; } Body(String bodyName, Body orbitsAround){ this(); name = bodyName; orbits = orbitsAround; } public long id(){ return idNum; } public Body orbitsAround(){ return orbits; } public void orbitsAround(Body around){ orbits = around; } public String toString(){ String desc = idNum + "("+ name +")"; if (orbits != null) desc += " orbits "+ orbits.toString(); return desc; }}class Attr { private final String name; private Object value = null; public Attr(String name) { this.name = name; } public Attr(String name,Object value) { this.name = name; this.value = value; } public String getName() { return name; } public Object getValue() { return value; } public Object setValue(Object newValue) { Object oldVal = value; value = newValue; return oldVal; } } Body(天体)类和Attr(属性)类
  • 14. 将属性(Attr类的实例)和对象(Body类的实例)联系起来 1. Attr类和Body类的复合(在Body对象中包含一个Attr对象的集合) 2. Attr类与Body类间的继承(在类层次上从Body扩展新类,在新类中扩展一组Attr对象) 问题: Java类只支持单继承,既每个类只能有一个超类。导致Attr特性将加到Object基类中,使Object不断膨胀,无法管理。 解决 Java类提供接口实现多重继承。7.4 接口的使用1. class HaveAttrObject extends OObject implements Attributed interface Attributed { void add(Attr newAttr); Attr find(String attrName); Attr remove(String attrName); java.util.Iterator attrs(); } 2. class AttributedImp1 implements Attributedclass HaveAttrObject extends OObject implements Attributed { AttributedImp1 attrImp1 = new AttributedImp1(); add(…){attrImp1.add(…); … }
  • 15. Attributed接口的一个简单实现AttributedImp1类。7.4 接口的使用import java.util.*; class AttributedImp1 implements Attributed { protected HashMap attrTable = new HashMap(); public void add(Attr newAttr){ attrTable.put(newAttr.getName(),newAttr); } public Attr find(String name){ return (Attr)attrTable.get(name); } public Attr remove(String name){ return (Attr)attrTable.remove(name); } public Iterator attrs(){ return attrTable.values().iterator(); } }interface Attributed { void add(Attr newAttr); Attr find(String attrName); Attr remove(String attrName); java.util.Iterator attrs(); }
  • 16. 7.4 接口的使用 import java.util.Iterator; class AttributedBody extends Body implements Attributed { AttributedImpl attrImpl = new AttributedImpl(); AttributedBody() { super();} AttributedBody(String name,Body orbits){ super(name,orbits); } // Forward all Attributed calls to the attrImpl object public void add(Attr newAttr) { attrImpl.add(newAttr); } public Attr find(String name) { return attrImpl.find(name); } public Attr remove(String name) { return attrImpl.remove(name); } public Iterator attrs() { return attrImpl.attrs(); } }复合模式
  • 17. 7.4 接口的使用class Body+ long idNum + String name + Body orbits -- static long nextIDBody ( )class Attr-- String name -- Object value+ Attr ( String nameOf ) + Attr ( String nameOf, Object valueOf ) + String nameOf ( Attr newAttr ) + Object valueOf ( ) + Object valueOf ( Object newValue )interface Attributed+ void add ( Attr newAttr ) + Attr find ( String attrName ) + Attr remove ( String attrName ) + java.util.Enumeration attrs ( )class AttributedBody AttributedImp1 attrImp1AttributedBody ( ) AttributedBody ( String name, Body orbits ) + void add ( Attr newAttr ) + Attr find ( String name ) + Attr remove ( String name ) + Enumeration attrs ( )class AttributedImp1# Hashtable attrTable+ void add ( Attr newAttr ) + Attr find ( String name ) + Attr remove ( String name ) + Enumeration attrs ( )
  • 18. 接口和抽象类的异同点 当进行一些抽象因素设计时,可选择抽象类或接口。 若多重继承占主要地位,则选择接口 若简单单继承占主要地位,则选择抽象类 若是某个需要进一步扩展的重要类,不论是否抽象,都应该是某个接口的实现。相同点不同点接口 1. 类型 2. 不可直接实例化 1. 可多重继承, 2. 纯抽象,不涉及实现,只包含未实现的公用方法和常量抽象类1. 一个类只能扩展一个另外的类。 2. 可包含部分实现,可有protected、private、static方法7.5 何时使用接口
  • 19. 一个接口由常量和未给定实现的方法构成。一个接口可扩展多个接口,接口集合组成“丛形图”。 类和接口间的关系: 类可实现多个接口,即对接口中的每个方法都给出实现。 一个接口可被多个类实现。(接口与类间是多对多的关系) 一个接口说明了一种类型,所以可用接口类型来说明引用变量的类型。该类型的引用变量可指向实现该接口的任一个类的对象。因此可用接口调用不同类的相同方法。7.6 小结YXABZC接口类
  • 20. 声明接口的语法是: public interface 接口名 extends 借口列表 接口的用途: 通过接口可以抽取不相关类的相同行为 通过接口可以说明多个类需要实现的共同方法 通过接口可以了解对象的交互界面,而无需了解对象对应的类 一个类型指一组值集及其上的操作集所构成的二元组。Java中,值为对象,操作既为对象提供的方法类(C)接口(I)值集类C及类C的扩展类的实例对象接口I的实现类及扩展类的实例对象操作集类C中定义的方法接口I中定义的方法7.6 小 结
  • 21. 若类C实现了接口I,那么类C及其扩展类所实例化的对象既属于类C的类型,也属于接口I的类型,即该对象可以作为这两种类型来引用。6.8 小 结ICZZ z = new Z( ); C c = new Z(); I i = new Z();