Java程序设计 第10章 抽象类和接口
学习目标 设计和使用抽象类 掌握接口的声明和实现 了解抽象类和接口的异同 掌握基本数据类型的包装类型 了解JDK1.5中基本数据类型与包装类型的自动转换
抽象类和抽象方法 Java中可以定义不含方法体的方法,方法的方法体由该类的子类根据自己的情况去实现,这样的方法称为抽象方法(abstract method),包含抽象方法的类必须是抽象类(abstract class)。 一个类C如果满足下面的任一条件,则该类包含抽象方法: 类C显式地包含一个抽象方法的声明; 类C的父类中声明的抽象方法未在类C和它的父类中实现; 类C的父接口中声明或继承一个方法,并且类C中未声明或继承一个方法来实现它。
注意 抽象类和抽象方法必须用abstract关键字来修饰。 只有实例方法可以声明为抽象方法。 抽象类不能被实例化,即不能用new关键字创建对象。 抽象类的父类可以是具体类。 具体子类必须实现抽象父类中所有抽象方法,否则子类需要声明为抽象类。
抽象类示例 Example:GeometricObject.java,Circle.java, Rectangle.java, - radius : double + <<Override>> getRadius () setRadius (double radius) getArea () getPerimeter () toString () : void : String GeometricObject color filled : boolean getColor () setColor (String color) isFilled () setFilled (boolean filled) Rectangle width height getWidth () setWidth (double width) getHeight () setHeight (double height) Example:GeometricObject.java,Circle.java, Rectangle.java, TestGeometricObject.java
接口 接口是常量和抽象方法的集合。接口是能力、规范、协议的反映。 语法 接口中的数据字段隐含为public static final [modifier] interface interfaceName { constant_declaration* abstract_method_declaration* } 接口中的数据字段隐含为public static final 接口体中的方法隐式地声明为public abstract
使用接口 可以在能够使用任何其他数据类型的地方使用接口。 接口类型属于引用类型,接口类型的变量可以存储: 类实现接口的语法 空引用(null) 任何实现该接口的类的实例的引用 类实现接口的语法 [modifier] class className [extends superclass] [implements interfaceNameList ] { member_declaration* } 除非类被声明为abstract,所有父接口中声明的成员方法必须被实现,或者通过在类中声明或者通过从父类继承已有的方法声明。
例1 public interface Flyer { void takeOff(); void land(); void fly(); } public class Airplane implements Flyer { public void takeOff() { // 加速直到离地升空 // 收起起落架 public void land() { // 放下起落架 // 减速并降低副翼直到降落 // 刹车 public void fly() { // 保持引擎运转
例2
例3
例4
接口继承 一个接口可以继承多个接口。 语法 [modifier] interface interfaceName [extends interfaceNameList] { declaration* } 如果接口声明中提供了extends子句那么该接口就继承了父接口的成员类型、方法和常量。这些接口称为声明接口的直接父接口。 任何实现该接口的类,必须实现该接口继承的其他接口。
接口和抽象类的比较 接口 抽象类 多重继承 方法 数据字段 现有类 含义 适用性 简洁性 添加功能 一个类可以实现多个接口 一个类只能扩展一个抽象类 方法 接口不能提供任何代码 抽象类可以提供完整代码、缺省代码以及用于覆盖的存根。 数据字段 只包含public static final常量,常量必须在声明时初始化。 可以包含实例变量和静态变量。静态和实例初始化代码可用于常量计算。 现有类 任何现有的类都可以添加一个接口的实现 现有类必须重写,只从抽象类派生 含义 接口通常用于描述一个类的外围能力,而不是核心特征,例如Automobile类可以实现Recyclable接口,而Recyclables可以应用于其他不相关的对象。类与接口之间的是-able或者can do的关系。 抽象类定义了它的后代的核心特征。例如Person类包含了Student类的核心特征。派生类与抽象类之间是is-a的关系。 适用性 所有的实现只是共享方法签名 所有实现大同小异,并且共享状态和行为 简洁性 接口中的常量都被假定为public static final,可以省略。不能调用任何方法计算这些常量的初始值。接口中的方法被假定为public abstract。 可以在抽象类中放置共享代码。可以使用方法来计算实例和静态变量(常量)的初始值。必须用abstract显式声明方法为抽象方法。 添加功能 如果为接口添加一个新的方法,则必须查找所有实现该接口的类,并为他们逐一提供该方法的实现。 如果为抽象类提供一个方法,可以选择提供一个缺省的实现,那么所有已存在的代码不需要修改就可以继续工作。
基本数据类型的包装类 作用 包装类的对象的值是不变的 为基本数据类型提供方法和常量值 用于只能处理对象引用的地方 Comparable Object Number Character Boolean Byte Short Integer Long Float Double
构造函数与通用方法 构造函数 通用方法 以一个对应的基本数据类型为参数 以字符串为参数(除了Character) public static Type valueOf(String str) public String toString() public type typeValue() public int compareTo(Type other) public int compareTo(Object obj) public boolean equals(Object obj) public int hashCode()
Number 方法 public abstract int intValue() public abstract long longValue() public abstract float floatValue() public abstract double doubleValue() public byte byteValue() public short shortValue()
整数包装类 Byte, Short, Integer, Long 方法 public static type parseType(String s) public static type parseType(String s, int radix) public static Type valueOf(String s, int radix) public static String toString(type val, int radix) public static String toHexString(type val) public static String toOctalString(type val) public static String toBinaryString(type val)
浮点包装类 Float, Double 常量 方法 POSITIVE_INFINITY NEGATIVE_INFINITY NAN public boolean isInfinite() public boolean isNaN() public static type parseType(String s) public static String toString(int i)
例 排序对象数组 编写程序,对Comparable对象数组进行排序。 Example:GenericSort.java
基本类型与包装类之间的自动转换 JDK1.5允许基本类型和包装类之间的自动转换。 将基本类型的值转换为包装类对象,称为装箱(boxing) 将包装类对象转换为基本类型的值,称为开箱(unboxing) Integer intObject = 2; 等价于 Integer intObject = new Integer(2);