接口、内部类、泛型

接口提供方法声明与方法实现相分离的机制,使多个类之间表现出共同的行为能力。接口机制使Java具有实现多继承的能力 (与抽象类的不同)。内部类使类具有嵌套能力。

一、接口与实现类接口的类

接口(interface)是一组抽象方法、常量和内嵌类型的集合。接口是一种数据类型,接口采用抽象的形式来描述约定因此接口只有被类实现后才有意义。接口声明的抽象方法在实现接口的多个类中表现出多态性。

接口声明 :使用关键字 interface 声明接口,语法如下

[public]  interface  接口 <泛型> [extends 父接口列表]{
    [public] [static] [final] 数据类型 成员变量 = 常量值;
    [public] [abstract] 返回值类型 成员方法[参数列表];			// 抽象方法
}

声明接口说明如下:
1.接口中的成员变量都是常量,声明时都必须赋值,默认修饰符 public static final;不能声明实例变量。

2.接口中的成员方法都是抽象的实例成员方法,默认修饰符 public abstract 不能声明为 static。

3.接口中不能包含构造方法,因为构造方法是不能抽象的。

4.接口的访问控制权限是public或缺省的。

5.接口没有任何具体实现,也就不能创建实例。

声明实现接口的类

使用关键字 implements 声明一个类来实现指定的接口。语法如下

[修饰符] class 类<泛型> [extends 父类] [implements 接口列表]

一个类可以实现多个接口,多个接口之间用逗号分隔,一个非抽象类如果要声明实现多个接口,则它必须要实现(覆盖)所指定接口的所有抽象方法。方法的参数列表必须相同。否则必须声明为抽象类。

接口是多继承的

一个接口可以继承多个父接口。

接口是引用数据类型

接口与抽象类的区别 (从语法和作用上,接口与抽象类很像)

1.抽象类为子类约定方法声明,抽象类可以提供部分实现,包括构造方法等。抽象方法在多个子类中表现出多态性。

2.接口为多个互不相关的类约定某一特性的方法声明,在类型层次表达对象拥有的属性。接口没有实现部分。接口是多继承的。一个类可以实现多个接口,就具有多种特性。

单继承与多继承

类单继承的优点:一个类只能继承一个父类的实现使得每个子类和后代构成一颗具有层次结构的树。

类的多继承存在二义性问题 如果一个类能够继承多个父类,当父类中存在相同成员方法时子类究竟执行那一个父类中的方法,这是多继承存在的二义性问题。

接口中也会有这样的二义性问题编译器会指出存在二义性错误。

二、内部类和内部接口

内部类和内部接口是声明在其他类或接口内部的内嵌类型,包含内嵌类型的类或者接口称为外部类型。

内嵌类型的两个目的: 类型嵌套和对象嵌套。静态嵌套类型用于定义类型的嵌套结构。实例类型嵌套用于定义对象的嵌套结构。

public class Pixel{			// 像素类,外层类型,外部类
    public static interface ColorConstant			// 颜色常量接口,静态内部接口,类型嵌套
    public static class Color extends Object implements ColorConstant    // 颜色类,静态内部类
}

外层类型包含内嵌类型,两则构成嵌套结构。内嵌类型是外层类型的成员,因此,内嵌类型既有类型的特性,也有类中成员的特性。

1.内部类作为类型的特性

内嵌类型不能与外层类型同名。

内部类中可以声明成员变量和成员方法, 内部类成员可以与外部类成员同名,内部接口中可以声明成员常量和抽象成员方法。

内部类可以继承父类或实现接口。

可以声明内部类为抽象类,该抽象类必须被其它内部类继承 内部接口也必须别其他内部类实现。

2.内部类作为成员的特性

  • 使用运算符 “ . ” 引用内嵌类型,语法格式如下
外层类型.内嵌类型
  • 内嵌类型具有类中成员的 4 种访问控制权限,当内部类可被访问时,才能考虑内部类的成员访问控制权限。
  • 作为成员,内嵌类型与其外层类型彼此信任能访问对方所有成员。
  • 内部接口总是静态的。内部类可声明是静态的或实例的,静态内部类能够声明静态成员。但不能引用外部类的实例成员。实例内部类不能声明静态成员。
  • 在实例内部类中,使用以下语法格式引用或调用外部类当前实例的成员变量或实例成员方法。
外部类.this.成员变量						// 引用外部类当前实例的成员变量
外部类.this.实例成员方法(参数列表)			// 调用外部当前实例的成员方法三、泛型

三、泛型

泛型是对类型系统的一种强化措施。泛型可使一个类或者一个方法可在多种类型的对象上进行操作 从而减少数据类型的转换。避免了数据类型转换的潜在错误。增强了编译时刻的类型安全。