Java——接口的细节

接口的细节

1、接口中的变量

接口中可以定义变量,语法如下所示:

java 复制代码
public interface Interface1 {
    public static final int a = 0;
}

这里定义了一个变量int a,修饰符是public static final,但这个修饰符是可选的,即使不写,也是public staticfinal。这个变量可以通过"接口名.变量名"的方式使用,如Interface1.a。

2、接口的继承

接口也可以继承,一个接口可以继承其他接口,继承的基本概念与类一样,但与类不同的是,接口可以有多个父接 口,代码如下所示:

java 复制代码
public interface IBase1 {
    void method1();
}
public interface IBase2 {
    void method2();
}
public interface IChild extends IBase1, IBase2 {
}

3、类的继承与接口

类的继承与接口可以共存,换句话说,类可以在继承基类的情况下,同时实现一个或多个接口,语法如下所示:

java 复制代码
public class Child extends Base implements IChild {
  //主体代码
}

关键字extends要放在implements之前。

4、instanceof

与类一样,接口也可以使用instanceof关键字,用来判断一个对象是否实现了某接口,例如:

java 复制代码
Point p = new Point(2,3);
if(p instanceof MyComparable){
    System.out.println("comparable");
}

5、使用接口替代继承

继承至少有两个好处:一个是复用代码;另一个是利用多态和动态绑定统一处理多种不同子类的对象。

使用组合替代继承,可以复用代码,但不能统一处理。使用接口替代继承,针对接口编程,可以实现统一处理不同类型的对象,但接口没有代码实现,无法复用代码。将组合和接口结合起来替代继承,就既可以统一处理,又可以复用代码了。

先增加一个接口IAdd,代码如下:

java 复制代码
public interface IAdd {
    void add(int number);
    void addAll(int[] numbers);
}

修改Base代码,让它实现IAdd接口,代码基本不变:

java 复制代码
public class Base implements IAdd{
    private static final int MAX_NUM = 1000;
    private int[] arr = new int[MAX_NUM];
    private int count;

    public void add(int number) {
        if(count < MAX_NUM) {
            arr[count++] = number;
        }
    }

    public void addAll(int[] numbers) {
        for(int num : numbers) {
            add(num);
        }
    }
}

修改Child代码,也是实现IAdd接口,代码基本不变:

java 复制代码
public class Child implements IAdd{
    private Base base;
    private long sum;

    public Child() {
        base = new Base();
    }

    public void add(int number) {
        base.add(number);
        sum += number;
    }

    public void addAll(int[] numbers) {
        base.addAll(numbers);
        for(int i = 0; i < numbers.length; i++) {
            sum += numbers[i];
        }
    }

    public long getSum() {
        return sum;
    }
}

Child复用了Base的代码,又都实现了IAdd接口,这样,既复用代码,又可以统一处理,还不用担心破坏封装。

6、Java 8和Java 9对接口的增强

需要说明的是,前面介绍的都是Java 8之前的接口概念,Java 8和Java 9对接口做了一些增强。在Java 8之前,接口中的方法都是抽象方法,都没有实现体,Java 8允许在接口中定义两类新方法:静态方法和默认方法,它们有实现体,比如:

java 复制代码
public interface IDemo {
    void hello();
    public static void test() {
        System.out.println("hello");
    }
    
    default void hi() {
        System.out.println("hi");
    }
}

test()就是一个静态方法,可以通过IDemo.test()调用。在接口不能定义静态方法之前,相关的静态方法往往定义在单独的类中,比如,Java API中,Collection接口有一个对应的单独的类Collections,在Java 8中,就可以直接写在接口中了,比如Comparator接口就定义了多个静态方法。

hi()是一个默认方法,用关键字default表示。默认方法与抽象方法都是接口的方法,不同在于,默认方法有默认的实现,实现类可以改变它的实现,也可以不改变。引入默认方法主要是函数式数据处理的需求,是为了便于给接口增加功能。

在没有默认方法之前,Java是很难给接口增加功能的,比如List接口​,因为有太多非Java JDK控制的代码实现了该接口,如果给接口增加一个方法,则那些接口的实现就无法在新版Java上运行,必须改写代码,实现新的方法,这显然是无法接受的。函数式数据处理需要给一些接口增加一些新的方法,所以就有了默认方法的概念,接口增加了新方法,而接口现有的实现类也不需要必须实现。看一些例子,List接口增加了sort方法,其定义为:

java 复制代码
default void sort(Comparator<? super E> c) {
    Object[] a = this.toArray();
    Arrays.sort(a, (Comparator) c);
    ListIterator<E> i = this.listIterator();
    for(Object e : a) {
        i.next();
        i.set((E) e);
    }
}

Collection接口增加了stream方法,其定义为:

java 复制代码
default Stream<E> stream() {
    return StreamSupport.stream(spliterator(), false);
}

在Java 8中,静态方法和默认方法都必须是public的,Java 9去除了这个限制,它们都可以是private的,引入private方法主要是为了方便多个静态或默认方法复用代码,比如:

java 复制代码
public interface IDemoPrivate {
   private void common() {
       System.out.println("common");
   }
   default void actionA() {
       common();
   }
   default void actionB() {
       common();
   }
}

这里,actionA和actionB两个默认方法共享了相同的common()方法的代码。

相关推荐
阿拉金alakin1 小时前
深入理解 Java 锁机制:CAS 原理、synchronized 优化与主流锁策略全总结
java·开发语言
myheartgo-on1 小时前
Java—方 法
java·开发语言·算法·青少年编程
雨落在了我的手上1 小时前
如何学习java?
java·开发语言·学习
范什么特西2 小时前
计算机杂记
java
RyFit2 小时前
SpirngAI
java
庞轩px2 小时前
第六篇:Spring用了哪些设计模式?——从单例到代理,拆解框架中的经典设计
java·spring·设计模式·bean·代理模式·aop·单例
神仙别闹2 小时前
基于 C# OpenPGP 的文件管理系统
开发语言·c#
宝贝儿好2 小时前
【LLM】第三章:项目实操案例:智能输入法项目
人工智能·python·深度学习·算法·机器人
番石榴AI2 小时前
纯 CPU 推理!0.1B 超轻量级端到端OCR模型,使用 Java 进行文档解析
java·开发语言·ocr