Java 多态(接口)
有两种意义的多态,一是操作名称的多态,即有多个操作具有相同的名字,但这些操作所接收的消息类型必须不同(方法重载)。另一种多态是和继承有关的多态,是指同一个操作被不同类型对象调用时可能产生不同的行为(方法重写,抽象方法,接口)。多态可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。
向上转型
父类的引用可以指向子类的对象,感觉像子类自动的向上转型为父类。向上转型时,会遗忘子类对象中与父类对象中不同的方法,也会覆盖与父类中相同的方法,即重写。也就是说如果我们定义了一个指向子类对象的父类引用类型,那么它除了能够引用父类中定义的所有属性和方法外,还可以使用子类强大的功能(指被子类重写的部分)。但是对于只存在于子类的方法和属性就不能获取。
实现条件
- 继承
- 重写
- 向上转型 (即父类引用指向子类对象)
实现方式
方式一:重写
方式二:抽象类和抽象方法
抽象方法只有声明,没有方法体,声明语法如下:
abstract void fun();
包含抽象方法的类即为抽象类,定义类时需要加上关键字
abstract
。抽象方法的具体实现在抽象类的子类中完成,所以显然不能用 final 修饰抽象方法。我们不能直接创建抽象类的对象,所以抽象类必须被继承,才能被使用。通常是定义引用变量指向子类对象。
方式三:接口
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法,是对类的一组需求描述。接口的思想在于它可以增加很多类都需要实现的功能,但并不关心功能的实现,使用相同接口的类不一定有继承关系。
声明语法
修饰符 interface 接口名称 [extends 其他的接口名] { // 常量定义 // 抽象方法 }
- 接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
- 接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键字。
- public 修饰的接口可以被任何一个类使用。如果一个接口不加 public 修饰,则称其为友好接口,可以被同一个包中的类使用。
- 接口中的方法都自动地被设置为 public ,接口中的域被自动设置为 public static final。
相关要点
除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。在类中实现接口的方法时,方法的名字、返回类型、参数个数及类型必须与接口中的完全一致。特别需要注意的是:接口中的方法默认是 public abstract 方法,所以在类中实现时必须用 public 来修饰,而且接口中的常量默认是 public static 常量。
接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
接口不是类,不能构造接口的对象。但是却可以声明接口的变量,接口的变量必须引用实现了接口的类的对象。如同使用 instanceof 检查一个对象是否属于某个特定类一样,也可以使用 instanceof 检查一个对象是否实现了某个特定的接口。
接口回调是指可以把实现某一接口的类创建的对象的引用赋给该接口声明的接口变量。那么该接口变量就可以调用被该类实现的接口中的方法。实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法。如果一个方法的参数是接口类型,就可以将任何实现该接口的类的实例的引用传递给该参数接口,那么参数接口就可以回调类实现的接口方法。
一个类只能继承一个抽象类,而一个类却可以实现多个接口。
多继承实现方式
修饰符 interface A extends 接口1,接口2{ } 修饰符 class B implements 接口1,接口2{ }
注意点
- 接口中所有的方法是抽象方法。
- 接口成员是 static final 类型,可以直接用类名或接口名调用。
- 一个接口能继承另一个接口,这和类之间的继承比较相似,使用extends关键字。
- 接口支持多继承,extends关键字只需要使用一次,在其后跟着继承接口。
- 没有任何方法的接口被称为标记接口,主要用于建立一个公共的父接口或向一个类添加数据类型。
参考资料
- 菜鸟教程:Java 接口
- 实验楼:Java编程语言(新版)
- Java2实用教程 (第三版)_ 耿祥义,张跃平