一.接口的定义:
接口可以理解为一种特殊的类,里面全部是由全局常量和公共的抽象方法所组成。接口是解决Java无法使用多继承的一种手段。在JDK1.8之前接口之中只能包含抽象方法,jdk1.8之后接口可以提供默认的实现方法 default,允许公有的静态方法存在。
二.接口的书写:
如果需要声明一个接口,我们使用interface这个关键字,在接口中的所有方法都必须只声明方法标识,而不要去声明具体的方法体,因为具体的方法体的实现是由继承该接口的类来去实现的,因此,接口并不用管具体的实现。
例:
interface interfaceName{
final int a=10;
public void func();
}
三.接口的特征:
1、接口不能直接使用new操作符创建一个接口对象
2、接口也可以看作是一种特殊的类,使用javac命令编译之后会产生字节码文件
3、接口里的方法都是默认抽象的(public abstract)
4、具体类实现接口,implements关键字
5、接口来说功能和实体是"有"的关系
6、接口中的变量都默认是常量,都是public static final的(不写的时候系统会默认常量关键字,但是不能写错,例如加个private)
7、接口可以有多个实现,接口和接口之间也是可以继承的
四.接口的使用:
我们可以把接口当做一个特殊的类去理解,一般的类可以通过new操作符去创建实例,但是接口不能使用new操作符,所以如果我们要实例化一个接口,我们只能通过一个类似于继承的方式通过继承接口的可以实例化对象的类去将接口进行一个实例化再去使用。
而如果我们希望某一类对象能够使用接口的话,那么我们就需要用implements关键字去让这个类来实现接口。
注意:如果我们要把接口实例化的话,我们就要在实例化接口的对象中对接口中的方法进行一个重写!而且重写后的方法封装范围不能小于原有方法,也就是不能小于接口中默认的public范围
例:
interface Compute{
public double computeMAndN(double m, double n);
}
class Add implements Compute{
@Override
public double computeMAndN(double m, double n) {
return m+n;
}//对接口中的方法进行了重写。
}
接口比起类来说具有更加灵活的优点。子类继承父类的时候会把父类的所有特征都继承,但是假如说有多个子类继承于同一个父类时,而这些子类又分别具有很多自己的特征,这时如果只是单纯地用继承并且在继承后不停地去修改子类,那么不如为每种不同的特征都去用接口来表达然后让不同的子类去实例化不同的接口那样来的便捷。
面试题:用接口和类去实现一个可以开关并且有密码锁的门:
例:
abstract class Door{
public abstract void openDoor();
public abstract void closeDoor();
}
interface Door1{
public void password();
int index = 10;
}
class SpecDoor extends Door implements Door1, a{
@Override
public void openDoor() {
System.out.println(index);
}
@Override
public void closeDoor() {
}
@Override
public void password() {
}
}
这道题主要考察的就是接口的运用,所有的门都具有开关这个特性,但是并不是所有的门都具有密码锁,所以在这里我们把密码锁这个特性做成一个接口,然后让需要有整个功能的类去对其进行实现,简化了代码。
五.Java中接口和抽象类的区分(面试考点):
1.抽象类可以有构造函数,接口不能有构造函数!抽象类中的构造函数只能被此抽象类使用,不能用于创建对象!
2.抽象类中既可以有抽象方法也可以有普通成员方法;接口中的方法都是public的,在JDK1.8之前接口只能包含抽象方法,在JDK1.8之后接口可以提供默认的实现方法 default,允许公有的静态方法存在。
3.抽象类中的成员变量与普通类的成员变量要求一样,但是接口中的成员变量都必须是public static final的。
4.抽象类表达了一种“是”的关系;接口表达了一种“有”的关系,接口可以多继承,比起类来说更加灵活。
例:
abstract class A{
protected A(){};
public abstract void fun1();
public void fun2(){
......
}
}//抽象类
interface B{
int index=0;
void fun1();
void fun2();
}//接口
六.Java中的一些重要接口:
1.用于比较的接口:Comparable接口和Comparator接口
这两个接口可以用于根据某一类对象的某个属性来对这类对象进行一个比较。常用于自定义数据类型的比较。
Comparable接口和Comparator接口都是基于compareTo去实现的,故在此附加上compare To的实现过程:
o1和o2每次只取一个数据,就一次只比较两个数据,假如比较7,8,9,5,6,那么第一次比较o1先取8,o2取7,接下来配合compareTo()实现这两个数的排序,o1.compareTo(o2)会返回一个int值,如果0说明o1和o2相等,如果返回负值,那么o1和o2会倒序排序,返回正值,那么o1和o2会正序排序。返回值之后这两个值就进行了排序,至此,这两个值已经排序好了,接下来第二次排序,o1取9,o2取8,第三次o1取5,o2取9…
Comparable接口:
此接口强行对实现它的每个类的对象进行整体排序。此排序被称为该类的自然排序 ,类的 compareTo方法被称为它的自然比较方法 。
实现此接口的对象列表(和数组)可以通过 Collections.sort(和 Arrays.sort )进行自动排序。
注compareTo:compareTo(Object obj)方法是java.lang.Comparable接口中的方法, 当需要对类的对象进行排序时,该类需要实Comparable接口,必须重写public int compareTo(T)方法。
需要实现的方法:
int compareTo(T o)
比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
参数: T-比较的对象所属的类 o - 要比较的对象。
返回:负整数、零或正整数,根据此对象是小于、等于还是大于指定对象。
抛出:ClassCastException - 如果指定对象的类型不允许它与此对象进行比较。
例:根据面积这一属性来对矩形对象构成的数组进行一个排序。
class Recantangle implements Comparable<Recantangle>{
int area;
@Override
public int compareTo(Recantangle o) {
if(this.area>o.area){
return 1;
}else{
return -1;
}
}
}
public class GY1123 {
public static void main(String[] args) {
Recantangle[] r=new Recantangle[5];
r[0]=new Recantangle();
r[0].area=2;
r[1]=new Recantangle();
r[1].area=32;
r[2]=new Recantangle();
r[2].area=8;
r[3]=new Recantangle();
r[3].area=4;
r[4]=new Recantangle();
r[4].area=16;
Arrays.sort(r);
for(Recantangle a : r){
System.out.println(a.area);
}
}
}
Comparator接口:
Comparator接口是对compare(Object o1, Object o2)方法进行重写。
注compare:.compare(Object o1, Object o2)方法是java.util.Comparator接口的方法, 它实际上用的是待比较对象的compareTo(Object obj)方法。
Comparator 和 Comparable 相同的地方:
他们都是java的一个接口, 并且是用来对自定义的class比较大小的。
而且Comparator 和 Comparable接口在实例化的时候,后边一定要加上“<希望比较的类名>”
例:
class Recantangle implements Comparable<Recantangle>{}
//Recantangle类实例化了Comparable接口
//Comparable接口比较的对象是Recantangle类的
Comparator 和 Comparable 的区别:
Comparator位于包java.util下,而Comparable位于包java.lang下。
Comparable接口将比较代码嵌入需要进行比较的类的自身代码中,而Comparator接口在一个独立的类中实现比较。
如果前期类的设计没有考虑到类的Compare问题而没有实现Comparable接口,后期可以通过Comparator接口来实现比较算法进行排序,并且为了使用不同的排序标准做准备,比如:升序、降序。
Comparable接口强制进行自然排序,而Comparator接口不强制进行自然排序,可以指定排序顺序。
例:使用Comparator接口实现People对象可比较
public class Person{
String name;
int age
}
class PersonComparator implements Comparator {
public int compare(Person one, Person another) {
int i = 0;
i = one.name.compareTo(another.name); // 使用字符串的比较
if(i == 0) { // 如果名字一样,比较年龄,返回比较年龄结果
return one.age - another.age;
} else {
return i; // 名字不一样, 返回比较名字的结果.
}
}
}
Collections.sort( personList , new PersonComparator())