8 面向对象编程 8.8 接口

8 面向对象编程

8.8 接口

8.8.1 基本介绍

接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来。语法:
interface 接口名{
//属性
//抽象方法
}
class 类名 implements 接口{
自己属性;
自己方法;
必须实现的接口的抽象方法
}
小结:接口是更加抽象的抽象的类,抽象类里的方法可以有方法体,接口里的所有方法都没有方法体【jdk7.0】。接口体现了程序设计的多态和高内聚低偶合的设计思想。
特别说明: Jdk8.0后接口类可以有静态方法,默认方法,也就是说接口中可以有方法的具体实现

8.8.2 注意事项和细节

  1. 接口不能被实例化
  2. 接口中所有的方法是 public方法, 接口中抽象方法, 可以不用abstract 修饰 图示:
    void aaa();
    实际上是 abstract void aa(); (右侧图示 void aaa(){} 是错误写法,被红叉标记 )
  3. 一个普通类实现接口,就必须将该接口的所有方法都实现。
  4. 抽象类实现接口,可以不用实现接口的方法。
    代码:
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 接口的多态特性

  1. 多态参数(前面案例体现) InterfacePolyParameter.java
    在前面的Usb接口案例,UsbInterface usb,既可以接收手机对象,又可以接收相机对象,就体现了接口多态(接口引用可以指向实现了接口的类的对象)

  2. 多态数组 InterfacePolyArr.java
    演示一个案例:给Usb数组中,存放 Phone 和 相机对象,Phone类还有一个特有的方法call(),请遍历Usb数组,如果是Phone对象,除了调用Usb接口定义的方法外,还需要调用Phone特有方法 call.

  3. 接口存在多态传递现象. 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() {
        // 这里可根据实际需求补充方法逻辑,目前为空实现
    }
}
posted @ 2025-08-11 23:31  *珍惜当下*  阅读(5)  评论(0)    收藏  举报