接口

接口

定义接口

public interface Electronic {
    // 常量
    String LED = "LED";

    // 抽象方法
    int getElectricityUse();

    // 静态方法
    static boolean isEnergyEfficient(String electtronicType) {
        return electtronicType.equals(LED);
    }

    // 默认方法
    default void printDescription() {
        System.out.println("电子");
    }
}

反编译后的字节码:

public interface Electronic
{

    public abstract int getElectricityUse();

    public static boolean isEnergyEfficient(String electtronicType)
    {
        return electtronicType.equals("LED");
    }

    public void printDescription()
    {
        System.out.println("\u7535\u5B50");
    }

    public static final String LED = "LED";
}

  • 接口中定义的变量会在编译的时候自动加上 public static final 修饰符

  • 没有使用 privatedefault 或者 static 关键字修饰的方法是隐式抽象的,在编译的时候会自动加上 public abstract 修饰符。

  • 接口不允许直接实例化

  • 接口可以是空的,既可以不定义变量,也可以不定义方法。

  • 不要在定义接口的时候使用final关键字,否则会报编译错误,因为接口就是为了让子类实现的,而final阻止了这种行为。

  • 接口的抽象方法不能是private、protected或者final否则编译器都会报错。

  • 接口的变量是隐式 public static final(常量),所以其值无法改变。

接口作用

  1. 使某些实现类具有我们想要的功能
  2. Java 原则上只支持单一继承,但通过接口可以实现多重继承的目的。
    • 菱形问题:ClassA和ClassB继承同一个父类,ClassC同时继承了ClassA和ClassB,ClassC的对象在调用ClassA和ClassB中重写的方法时,就不知道该调用ClassA的方法,还是ClassB的方法。
  3. 实现多态
    • 多态是指同一个事件发生在不同的对象上会产生不同的结果
    • 多态可以通过继承(extends)的关系实现,也可以通过接口的形式实现。

接口的三种设计模式

策略模式

  • 针对一组算法,将每一种算法封装到具有共同接口的实现类中,接口的设计者可以在不影响调用者的情况下对算法做出改变。
package test.Interface;

// CS玩家
interface CSPlayer {
    // 游戏策略
    void strategy();
}

class Cadian implements CSPlayer {

    @Override
    public void strategy() {
        System.out.println("ECO局变形金刚");
    }
}

class Jame implements CSPlayer {

    @Override
    public void strategy() {
        System.out.println("保狙,save,save");
    }
}

public class Test {
    // 参数作为接口
    public static void strategy(CSPlayer csPlayer) {
        csPlayer.strategy();
    }

    public static void main(String[] args) {
        // 为同一个方法传递不同的对象
        strategy(new Cadian());
        strategy(new Jame());
    }
}

适配器模式

  • 针对调用者的需求对原有的接口进行转接。
// CS玩家
interface CSPlayer {
    // 指挥
    void conduct();
    // 突破
    void breakthrough();
}
// 抽象类实现接口,并置空方法
abstract class AbstractCSPlayer implements CSPlayer {
    public void conduct() {}
    public void breakthrough() {}
}
// 新类继承适配器
class Cadian extends AbstractCSPlayer {
    @Override
    public void conduct() {
        System.out.println("指挥队友");
    }
}
class Niko extends AbstractCSPlayer {
    @Override
    public void breakthrough() {
        System.out.println("AK突破手");
    }
}
  • 接口中定义了两个方法,如果类直接实现该接口,需要对两个方法都进行实现。
  • 如果只需对其中一个方法进行实现,可以使用一个抽象类作为中间件,即适配器,用这个抽象类实现接口,并对抽象类中的方法置空。此时新类就可以绕过接口去继承抽象类,就可以只对需要的方法进行覆盖。

工厂模式

  • 需要啥就用对应的工厂生产
// CS玩家
interface CSPlayer {
    void duty();
}

// CSer学院
interface CSerFactory {
    CSPlayer createCSer();
}

class Sniper implements CSPlayer {
    @Override
    public void duty() {
        System.out.println("狙击手");
    }
}

class Breaker implements CSPlayer {
    @Override
    public void duty() {
        System.out.println("突破手");
    }
}

// 狙击手学院
class SniperFactory implements CSerFactory {
    @Override
    public CSPlayer createCSer() {
        return new Sniper();
    }
}

// 突破手学院
class BreakerFactory implements CSerFactory {
    @Override
    public CSPlayer createCSer() {
        return new Breaker();
    }
}

public class Test {
    public static void createCSer(CSerFactory factory){
        factory.createCSer().duty();
    }

    public static void main(String[] args) {
        createCSer(new SniperFactory());
        createCSer(new BreakerFactory());
    }
}

接口和抽象类的区别

  • 1、抽象类可以有方法体的方法,但接口没有(Java 8 以前)。
  • 2、接口中的成员变量隐式为 static final,但抽象类不是的。
  • 3、一个类可以实现多个接口,但只能继承一个抽象类。

语法层面

  • 抽象类可以提供成员方法的实现细节,而接口中只能存在 public abstract 方法;
  • 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的;
  • 接口中不能含有静态代码块,而抽象类可以有静态代码块;
  • 一个类只能继承一个抽象类,而一个类却可以实现多个接口。

设计层面

  • 抽象类是对一种事物的抽象,即对类抽象,继承抽象类的子类和抽象类本身是一种 is-a 的关系。而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。

  • 抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。

posted @ 2024-07-13 23:29  n1ce2cv  阅读(5)  评论(0编辑  收藏  举报