Java基础之接口篇

Overload和Override的区别?重载Overload:表示同⼀个类中可以有多个名称相同的⽅法,但这些⽅法的参数列表各不相同,参

数个数或类型不同

重写Override:表示⼦类中的⽅法可以与⽗类中的某个⽅法的名称和参数完全相同

接⼝是否可以继承接⼝?接⼝是否⽀持多继承?类是否⽀持多继承?接⼝⾥⾯是否可以有⽅法实现

接⼝⾥可以有静态⽅法和⽅法体

接⼝中所有的⽅法必须是抽象⽅法(JDK8之后就不是)

接⼝不是被类继承了,⽽是要被类实现

接⼝⽀持多继承, 类不⽀持多个类继承

⼀个类只能继承⼀个类,但是能实现多个接⼝,接⼝能继承另⼀个接⼝,接⼝的继承使⽤extends关

键字,和类继承⼀样

是否了解JDK8⾥⾯接⼝新特性

interface中可以有static⽅法,但必须有⽅法实现体,该⽅法只属于该接⼝,接⼝名直接调⽤

该⽅法

接⼝中新增default关键字修饰的⽅法,default⽅法只能定义在接⼝中,可以在⼦类或⼦接⼝

中被重写default定义的⽅法必须有⽅法体

⽗接⼝的default⽅法如果在⼦接⼝或⼦类被重写,那么⼦接⼝实现对象、⼦类对象,调⽤该

⽅法,以重写为准

本类、接⼝如果没有重写⽗类(即接⼝)的default⽅法,则在调⽤default⽅法时,使⽤⽗类

(接⼝) 定义的default⽅法逻辑

抽象类(abstract class)和接口(interface)有什么异 同?
答:
抽象类和接口都不能够实例化,但可以定义抽象类和接口类型的引用。一个类如 果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实 现,否则该类仍然需要被声明为抽象类。接口比抽象类更加抽象,因为抽象类中 可以定义构造器,可以有抽象方法和具体方法,而接口中不能定义构造器而且其 中 的 方 法 全 部 都 是 抽 象 方 法 。抽 象 类 中 的 成 员 可 以 是 pr iv at e 、默 认 、pr ot e c te d 、 pu b li c 的 ,而 接 口 中 的 成 员 全 都 是 pu b li c 的 。抽 象 类 中 可 以 定 义 成 员 变 量 , 而 接 口中定义的成员变量实际上都是常量。有抽象方法的类必须被声明为抽象类,而 抽象类未必要有抽象方法。

参考《Java核心技术卷》

6.1.1 接口概念
在Java程序设计语言中,接口不是类,而是对类的一组需求描述,这些类要遵从接口描述的统一格式进行定义。
我们经常听到服务提供商这样说:“如果类遵从某个特定接口,那么就履行这项服务”。下面给出一个具体的示例。Arrays类中的sort方法承诺可以对对象数组进行排序,但要求满足下列前提:对象所属的类必须实现了Comparable接口。
下面是Comparable接口的代码:

这就是说,任何实现Comparable接口的类都需要包含compareTo方法,并且这个方法的参数必须是一个Object对象,返回一个整型数值。
注释:在Java SE 5.0中,Comparable接口已经改进为泛型类型。

例如,在实现Comparable接口的类中,必须提供下列方法

还可以使用不带类型参数的“原始”Comparable类型。这样一来,compareTo方法就有一个Object类型的参数,必须手动将compareTo方法的这个参数强制转换为所希望的类型。稍后我们就会做这个工作,所以不用担心同时出现两个新概念。
接口中的所有方法自动地属于public。因此,在接口中声明方法时,不必提供关键字public。
当然,接口中还有一个没有明确说明的附加要求:在调用x.compareTo(y)的时候,这个compareTo方法必须确实比较两个对象的内容,并返回比较的结果。当x小于y时,返回一个负数;当x等于y时,返回0;否则返回一个正数。
上面这个接口只有一个方法,而有些接口可能包含多个方法。稍后可以看到,在接口中还可以定义常量。然而,更为重要的是要知道接口不能提供哪些功能。接口绝不能含有实例域,在Java SE 8之前,也不能在接口中实现方法。(在6.1.4节和6.1.5节中可以看到,现在已经可以在接口中提供简单方法了。当然,这些方法不能引用实例域——接口没有实例。)
提供实例域和方法实现的任务应该由实现接口的那个类来完成。因此,可以将接口看成是没有实例域的抽象类。但是这两个概念还是有一定区别的,稍后将给出详细的解释。
现在,假设希望使用Arrays类的sort方法对Employee对象数组进行排序,Employee类就必须实现Comparable接口。
为了让类实现一个接口,通常需要下面两个步骤:
1)将类声明为实现给定的接口。
2)对接口中的所有方法进行定义。
要将类声明为实现某个接口,需要使用关键字implements:

当然,这里的Employee类需要提供compareTo方法。假设希望根据雇员的薪水进行比较。以下是compareTo方法的实现:

在这里,我们使用了静态Double.compare方法,如果第一个参数小于第二个参数,它会返回一个负值;如果二者相等则返回0;否则返回一个正值。
警告:在接口声明中,没有将compareTo方法声明为public,这是因为在接口中的所有方法都自动地是public。不过,在实现接口时,必须把方法声明为public;否则,编译器将认为这个方法的访问属性是包可见性,即类的默认访问属性,之后编译器就会给出试图提供更严格的访问权限的警告信息。
我们可以做得更好一些。可以为泛型Comparable接口提供一个类型参数。

请注意,对Object参数进行类型转换总是让人感觉不太顺眼,但现在已经不见了。
提示:Comparable接口中的compareTo方法将返回一个整型数值。如果两个对象不相等,则返回一个正值或者一个负值。在对两个整数域进行比较时,这点非常有用。例如,假设每个雇员都有一个唯一整数id,并希望根据ID对雇员进行重新排序,那么就可以返回id-other.id。如果第一个ID小于另一个ID,则返回一个负值;如果两个ID相等,则返回0;否则,返回一个正值。但有一点需要注意:整数的范围不能过大,以避免造成减法运算的溢出。如果能够确信ID为非负整数,或者它们的绝对值不会超过(Integer.MAX_VALUE-1)/2,就不会出现问题。否则,调用静态Integer.compare方法。
当然,这里的相减技巧不适用于浮点值。因为在salary和other.salary很接近但又不相等的时候,它们的差经过四舍五入后有可能变成0。x<y时,Double.compare(x,y)调用会返回-1;如果x>y则返回1。
现在,我们已经看到,要让一个类使用排序服务必须让它实现compareTo方法。这是理所当然的,因为要向sort方法提供对象的比较方式。但是为什么不能在Employee类直接提供一个compareTo方法,而必须实现Comparable接口呢?
主要原因在于Java程序设计语言是一种强类型(strongly typed)语言。在调用方法的时候,编译器将会检查这个方法是否存在。在sort方法中可能存在下面这样的语句:

为此,编译器必须确认a[i]一定有compareTo方法。如果a是一个Comparable对象的数组,就可以确保拥有compareTo方法,因为每个实现Comparable接口的类都必须提供这个方法的定义。
注释:有人认为,将Arrays类中的sort方法定义为接收一个Comparable[]数组就可以在使用元素类型没有实现Comparable接口的数组作为参数调用sort方法时,由编译器给出错误报告。但事实并非如此。在这种情况下,sort方法可以接收一个Object[]数组,并对其进行笨拙的类型转换:

如果a[i]不属于实现了Comparable接口的类,那么虚拟机就会抛出一个异常。
程序清单6-1给出了对一个Employee类(程序清单6-2)实例数组进行排序的完整代码,用于对一个员工数组排序。
程序清单6-1 interfaces/EmployeeSortTest.java

程序清单6-2 interfaces/Employee.java

java.lang.Comparable1.0
·int compareTo(Tother)
用这个对象与other进行比较。如果这个对象小于other则返回负值;如果相等则返回0;否则返回正值。
java.util.Arrays 1.2
·static void sort(Object[]a)
使用mergesort算法对数组a中的元素进行排序。要求数组中的元素必须属于实现了Comparable接口的类,并且元素之间必须是可比较的。
java.lang.Integer 1.0
·static int compare(int x,int y)7
如果x<y返回一个负整数;如果x和y相等,则返回0;否则返回一个负整数。
java.lang.Double 1.0
·static int compare(double x,double y)1.4
如果x<y返回一个负数;如果x和y相等则返回0;否则返回一个负数。
注释:语言标准规定:对于任意的x和y,实现必须能够保证sgn(x.compareTo(y))=-sgn(y.compareTo(x))。(也就是说,如果y.compareTo(x)抛出一个异常,那么x.compareTo(y)也应该抛出一个异常。)这里的“sgn”是一个数值的符号:如果n是负值,sgn(n)等于-1;如果n是0,sgn(n)等于0;如果n是正值,sgn(n)等于1。简单地讲,如果调换compareTo的参数,结果的符号也应该调换(而不是实际值)。
与equals方法一样,在继承过程中有可能会出现问题。
这是因为Manager扩展了Employee,而Employee实现的是Comparable,而不是Comparable。如果Manager覆盖了compareTo,就必须要有经理与雇员进行比较的思想准备,绝不能仅仅将雇员转换成经理。

这不符合“反对称”的规则。如果x是一个Employee对象,y是一个Manager对象,调用x.compareTo(y)不会抛出异

posted on 2022-08-05 08:12  Arya32f  阅读(20)  评论(0编辑  收藏  举报

导航