8 面向对象编程 8.8 接口
8 面向对象编程
8.8 接口
8.8.1 基本介绍
接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来。语法:
interface 接口名{
//属性
//抽象方法
}
class 类名 implements 接口{
自己属性;
自己方法;
必须实现的接口的抽象方法
}
小结:接口是更加抽象的抽象的类,抽象类里的方法可以有方法体,接口里的所有方法都没有方法体【jdk7.0】。接口体现了程序设计的多态和高内聚低偶合的设计思想。
特别说明: Jdk8.0后接口类可以有静态方法,默认方法,也就是说接口中可以有方法的具体实现
8.8.2 注意事项和细节
- 接口不能被实例化
- 接口中所有的方法是 public方法, 接口中抽象方法, 可以不用abstract 修饰 图示:
void aaa();
实际上是 abstract void aa(); (右侧图示void aaa(){}
是错误写法,被红叉标记 ) - 一个普通类实现接口,就必须将该接口的所有方法都实现。
- 抽象类实现接口,可以不用实现接口的方法。
代码:
public class InterfaceDetail01 {
public static void main(String[] args) {
// 接口不能被实例化,所以下面这行代码会报错,已注释
// new IA();
}
}
// 1. 接口不能被实例化
// 2. 接口中所有方法默认是 public abstract(可省略 abstract 修饰),且访问修饰符只能是 public
interface IA {
// 等价于 public abstract void say();
void say();
// 等价于 public abstract void hi();
void hi();
}
// 3. 普通类实现接口,必须实现接口的所有抽象方法
class Cat implements IA {
@Override
public void say() {
// 实现 say 方法的具体逻辑
}
@Override
public void hi() {
// 实现 hi 方法的具体逻辑
}
}
// 4. 抽象类实现接口,可以不实现接口的抽象方法
abstract class Tiger implements IA {
// 可在此添加抽象类特有的属性或方法
}
InterfaceDetail02.java
5) 一个类同时可以实现多个接口 [举例]
6) 接口中的属性,只能是final的,而且是 public static final 修饰符。比如:
int a=1; 实际上是 public static final int a=1; (必须初始化)
7) 接口中属性的访问形式: 接口名.属性名
8) 接口不能继承其它的类,但是可以继承多个别的接口 [举例]
interface A extends B,C{}
9) 接口的修饰符 只能是 public 和默认,这点和类的修饰符是一样的。
代码:
public class InterfaceDetail02 {
public static void main(String[] args) {
// 证明接口中的属性是public static final
System.out.println(IB.n1); // 说明n1是static(可以通过接口名直接访问)
// IB.n1 = 30; // 编译错误,说明n1是final(不能被修改)
}
}
interface IB {
// 接口中的属性,默认是public static final修饰
int n1 = 10; // 等价于 public static final int n1 = 10;
void hi();
}
interface IC {
void say();
}
// 接口不能继承类,但可以继承多个其他接口
interface ID extends IB, IC { }
// 接口的修饰符只能是public和默认(同类的修饰符规则)
interface IE { }
// 一个类可以同时实现多个接口
class Pig implements IB, IC {
@Override
public void hi() {
// 实现IB接口的hi()方法
}
@Override
public void say() {
// 实现IC接口的say()方法
}
}
8.8.3实现接口vs继承类
public class ExtendsVsInterface {
public static void main(String[] args) {
LittleMonkey wuKong = new LittleMonkey("悟空");
wuKong.climbing();
wuKong.swimming();
wuKong.flying();
}
}
// 猴子类(父类)
class Monkey {
private String name;
public Monkey(String name) {
this.name = name;
}
// 猴子具备爬树能力
public void climbing() {
System.out.println(name + " 会爬树...");
}
public String getName() {
return name;
}
}
// 游泳接口(扩展功能)
interface Fishable {
void swimming();
}
// 飞翔接口(扩展功能)
interface Birdable {
void flying();
}
// 小猴子类(子类):继承父类并实现接口扩展功能
class LittleMonkey extends Monkey implements Fishable, Birdable {
public LittleMonkey(String name) {
super(name);
}
// 实现游泳功能
@Override
public void swimming() {
System.out.println(getName() + " 通过学习,可以像鱼儿一样游泳...");
}
// 实现飞翔功能
@Override
public void flying() {
System.out.println(getName() + " 通过学习,可以像鸟儿一样飞翔...");
}
}
- 接口和继承解决的问题不同
- 继承的价值主要在于:解决代码的复用性和可维护性。
- 接口的价值主要在于:设计,设计好各种规范(方法),让其它类去实现这些方法。即更加的灵活..
- 接口比继承更加灵活
- 接口比继承更加灵活,继承是满足 is - a的关系,而接口只需满足 like - a的关系。
- 接口在一定程度上实现代码解耦[即: 接口规范性+动态绑定机制]
8.8.4 接口的多态特性
-
多态参数(前面案例体现) InterfacePolyParameter.java
在前面的Usb接口案例,UsbInterface usb,既可以接收手机对象,又可以接收相机对象,就体现了接口多态(接口引用可以指向实现了接口的类的对象) -
多态数组 InterfacePolyArr.java
演示一个案例:给Usb数组中,存放 Phone 和 相机对象,Phone类还有一个特有的方法call(),请遍历Usb数组,如果是Phone对象,除了调用Usb接口定义的方法外,还需要调用Phone特有方法 call. -
接口存在多态传递现象. InterfacePolyPass.java
interface InterA {
void fA();
}
class B implements InterA {
@Override
public void fA() {
System.out.println("fA~");
}
public void fB() {
System.out.println("fB~");
}
}
class C extends B { }
代码:
InterA a = new C();
//因为 C实现了InterA接口,所以可以向上转型
//如果 a 运行类型是 C,而 C 实现了 InterA,所以可以传递
InterA a2 = new B();
代码:
// 演示接口多态参数的类
class InterfacePolyParameter {
public static void main(String[] args) {
// 接口的多态体现,接口类型变量指向实现类对象
IF if01 = new Monster();
if01 = new Car();
// 继承体现的多态,父类类型变量指向子类对象
AAA a = new BBB();
a = new CCC();
}
}
// 定义接口 IF
interface IF {}
// Monster 类实现 IF 接口
class Monster implements IF {}
// Car 类实现 IF 接口
class Car implements IF {}
// 定义父类 AAA
class AAA {}
// BBB 类继承 AAA 类
class BBB extends AAA {}
// CCC 类继承 AAA 类
class CCC extends AAA {}
// 演示接口多态数组的类
class InterfacePolyArr {
public static void main(String[] args) {
// 多态数组,创建 Usb 类型数组
Usb[] usbs = new Usb[2];
usbs[0] = new Phone_();
usbs[1] = new Camera_();
// 遍历数组,调用接口方法,若为 Phone_ 对象则调用特有方法
for (int i = 0; i < usbs.length; i++) {
usbs[i].work(); // 动态绑定,调用实现类的 work 方法
if (usbs[i] instanceof Phone_) {
((Phone_) usbs[i]).call();
}
}
}
}
// 定义 Usb 接口
interface Usb {
void work();
}
// Phone_ 类实现 Usb 接口
class Phone_ implements Usb {
public void call() {
System.out.println("手机可以打电话...");
}
@Override
public void work() {
System.out.println("手机工作中...");
}
}
// Camera_ 类实现 Usb 接口
class Camera_ implements Usb {
@Override
public void work() {
System.out.println("相机工作中...");
}
}
// 演示接口多态传递现象的类
class InterfacePolyPass {
public static void main(String[] args) {
// 接口类型变量指向实现类对象,体现接口多态
IG ig = new Teacher();
// 因 IG 继承 IH,Teacher 实现 IG,所以可将 Teacher 对象赋值给 IH 类型变量,体现多态传递
IH ih = new Teacher();
}
}
// 定义接口 IH
interface IH {
void hi();
}
// 定义接口 IG,继承 IH 接口
interface IG extends IH {}
// Teacher 类实现 IG 接口
class Teacher implements IG {
@Override
public void hi() {
// 这里可根据实际需求补充方法逻辑,目前为空实现
}
}