接口
接口
定义接口
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
修饰符 -
没有使用
private
、default
或者static
关键字修饰的方法是隐式抽象的,在编译的时候会自动加上public abstract
修饰符。 -
接口不允许直接实例化
-
接口可以是空的,既可以不定义变量,也可以不定义方法。
-
不要在定义接口的时候使用final关键字,否则会报编译错误,因为接口就是为了让子类实现的,而final阻止了这种行为。
-
接口的抽象方法不能是private、protected或者final否则编译器都会报错。
-
接口的变量是隐式
public static final
(常量),所以其值无法改变。
接口作用
- 使某些实现类具有我们想要的功能
- Java 原则上只支持单一继承,但通过接口可以实现多重继承的目的。
- 菱形问题:ClassA和ClassB继承同一个父类,ClassC同时继承了ClassA和ClassB,ClassC的对象在调用ClassA和ClassB中重写的方法时,就不知道该调用ClassA的方法,还是ClassB的方法。
- 实现多态
- 多态是指同一个事件发生在不同的对象上会产生不同的结果
- 多态可以通过继承(
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
的关系。而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。 -
抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。
本文作者:n1ce2cv
本文链接:https://www.cnblogs.com/sprinining/p/18300989
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步