Java接口详解

简介: Java接口详解


接口方法

       在Java设计的时候, 我们所说的接口,不同于类,我们尝尝希望一个类能满足某个特定的功能,或者需求.

       我们在使用Arrays类中的sort方法对对象数组进行排序,但是对象所属的类必须实现Comparable接口:

可以看到里面只有一个方法:

public  interface Comparable {
    int compareTo(Object other);
}

       在这个接口中, compareTo方法是抽象的, 它没有具体的实现, 任何实现Comparable接口的类都需要包含一个compareTo方法, 这个方法必须接收一个Object参数,并返回一个整数, 否则的话这个类也应当是抽象的.

       在接口中所有的方法都是默认public, 在声明的时候可以不必提供public 关键字:

       为了让类实现一个接口, 需要完成下面两个步骤:

  1. 将类声明为实现给定的接口
  2. 对接口中的所有方法提供定义

       对于一个类,声明接口需要使用到关键字implements

       例如: class  Exam implements  Comparable

       当然, 现在这个Exam类需要提供compareTo方法, 假设我们比较的是Exam类里面的一个数caseInt的大小, 接下来是对其compareTo进行实现:

public int compareTo(Object other) {
    Exam otherExam = (Exam)other;
    return Double.compare(caseInt, other.caseInt);
}

       这里使用了静态方法Double.compare 方法 : 如果第一个参数小于第二个参数, 它会返回一个负值, 如果两者相等就返回0, 否则返回一个正值

注意: 在接口的声明中没有将compareTo方法声明为public, 这是因为接口中所有的方法都是自动public的方法, 但是在实现某个接口的类中方法, 就必须要把继承来的接口方法声明为public, 否则编译器将认为这个方法的访问属性是包可访问. 说这类中默认的访问属性, 之后编译就会报错, 指出你试图提供更严格的访问权限\

       提出一个问题: 为什么我们不能直接在Exam类里面提供一个compareTo方法呢?

       使用接口的主要原因是, Java是程序设计语言是一个强类型的语言, 在使用某个方法的时候, 编译器需要能够确认这个方法确实存在, 在sort 方法里面会有下面这样类似的实现:

if (a[i].compareTo(a[j]) > 0) {
    // rearrange a[i] and a[j];
}

       编译器必须确认a[i] 一定存在这个compareTo方法, 如果a是一个Comparable对象的数组, 那么就可以确保存在compareTo方法, 因为每个实现comparable接口的类都需要提供这个compareTo方法.

       在一些简单的实现了Comparable的接口的类中重写compareTo方法, 尝尝使用Integer类和Double类中的静态方法compare来比较这种比较简单类型的数值比较, 如果是复杂的比较需要自己去自定义比较的内容:

  • static int compare (int x, int y) : 如果x < y 放回一个负数, 如果x == y 返回0, 否则返回正整数
  • static int compare (double x, double y) : 同上

接口的属性

       接口不是类, 具体一点就是不能使用new 关键字来实例化一个接口, 例如:

        尽管不能构造接口的对象, 但是仍然可以声明接口变量:

        接口变量必须引用一个实现了这个接口的类对象:

x = new A();

       接下来, 可以使用instanceof来检查一个对象是否实现了某个特定的接口:

if (exam instanceof Comparable) {
    // ......
}

       现在, 假设Exam接口中包含了恶一个常量(接口中不能包含实例字段, 但是可以包含常量) :

interface Exam {
    void function();
    int a = 1;
}

       接口中的字段总是public static final的

package Thread1Demo;
 
import java.awt.*;
 
public class Main {
    public static void main(String[] args ) {
        Exam y;
        // 接口中的字段总是public static final 的
        int ret = Exam.a;
        System.out.println(ret);
        // Exam.a = 2;   Cannot assign a value to final variable 'a'
        //A a = new A();
        //a.B = 20;    Cannot assign a value to final variable 'B'
    }
}
interface Exam {
    void function();
    int a = 1;
}
 
class A implements Exam {
    public final int B = 10;
    @Override
    public void function() {
 
    }
}

       可以直接访问接口中的常量

       如果实现了某个接口的类中存在和接口中相同变量名的变量, 那么优先级如何?

package Thread1Demo;
 
import java.awt.*;
 
public class Main {
    public static void main(String[] args ) {
        A exa = new A();
        System.out.println(exa.a);
        
    }
}
interface Exam {
    void function();
    int a = 1;
}
 
class A implements Exam {
    public final int a = 10;
    @Override
    public void function() {
 
    }
}

可以看到是类中的变量优先.

       同方法在接口中的声明一样, 常量在接口中的声明是默认public static fianl的, 也就是说在接口中声明的时候不需要加上public static final:

 


目录
相关文章
|
1天前
|
存储 Java 测试技术
滚雪球学Java(61):从源码角度解读Java Set接口底层实现原理
【6月更文挑战第15天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
8 1
滚雪球学Java(61):从源码角度解读Java Set接口底层实现原理
|
2天前
|
Java
深入理解 Java 8 函数式接口:定义、用法与示例详解
深入理解 Java 8 函数式接口:定义、用法与示例详解
4 1
|
2天前
|
安全 Java
Java 并发编程详解:Lock 接口及其实现 ReentrantLock
Java 并发编程详解:Lock 接口及其实现 ReentrantLock
9 1
|
3天前
|
Java
JAVA高级部分(接口)
JAVA高级部分(接口)
|
3天前
|
Java
Java动态获取某个接口下所有的实现类对象集合
Java动态获取某个接口下所有的实现类对象集合
9 1
|
3天前
|
JSON Java 数据格式
java读取接口返回的json数据 (二)
java读取接口返回的json数据 (二)
17 5
|
3天前
|
JSON Java 数据格式
java读取接口返回的json数据
java读取接口返回的json数据
17 5
|
3天前
|
Java
Java基础7-一文搞懂抽象类和接口,从基础到面试题,揭秘其本质区别(二)
Java基础7-一文搞懂抽象类和接口,从基础到面试题,揭秘其本质区别(二)
9 0
|
3天前
|
设计模式 Java 内存技术
Java基础7-一文搞懂抽象类和接口,从基础到面试题,揭秘其本质区别(一)
Java基础7-一文搞懂抽象类和接口,从基础到面试题,揭秘其本质区别(一)
12 0
|
4天前
|
Java 开发者
Java中的Lambda表达式和函数式接口
在Java 8中,Lambda表达式的引入为Java带来了前所未有的便利性。它允许开发者以更简洁、更高效的方式处理集合、线程等。本文将深入探讨Lambda表达式的概念、用法以及与函数式接口的关系,帮助读者更好地理解和应用这一特性。