目录
接口方法
接口的属性
接口方法
在Java设计的时候, 我们所说的接口,不同于类,我们尝尝希望一个类能满足某个特定的功能,或者需求.
我们在使用Arrays类中的sort方法对对象数组进行排序,但是对象所属的类必须实现Comparable接口:
可以看到里面只有一个方法:
public interface Comparable {
int compareTo(Object other);
}
在这个接口中, compareTo方法是抽象的, 它没有具体的实现, 任何实现Comparable接口的类都需要包含一个compareTo方法, 这个方法必须接收一个Object参数,并返回一个整数, 否则的话这个类也应当是抽象的.
在接口中所有的方法都是默认public, 在声明的时候可以不必提供public 关键字:
为了让类实现一个接口, 需要完成下面两个步骤:
- 将类声明为实现给定的接口
- 对接口中的所有方法提供定义
对于一个类,声明接口需要使用到关键字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: