接口是抽象的最高境界
Java除了平台无关的特点外,从语言的角度来看,Java的接口是该语言的又一特色。Java舍弃了C++语言中多重继承的机制,使得编写的代码更加健壮和便于维护,因为多继承不符合人的思维模式,就像生活中,人只有一个父亲,而不是多个。尽管多继承可以使编程者更加灵活的设计程序,但是程序会显得难于阅读和维护。
Java不支持多继承性,即一个类只能有一个父亲。通过继承方式只能得到一个多态。单继承性使得Java简单,易于管理和维护。那么为了克服Java单继承的缺点,Java使用了接口,一个类可以实现多个接口,Java的接口更加符合人的思维方式。
使用关键字interface来定义一个接口。
接口的定义和类的定义很相似,分为接口的声明和接口体。
1)接口声明
接口通过使用关键字interface来声明,格式:
interface 接口的名字
示例:
test.java
public interface Test { //声明了一个接口
}
2)接口体
接口体中包含常量的声明(没有变量)和方法定义两个部分。接口体中只有抽象方法,没有普通方法,而且接口体中所有的常量的访问权限一定都是public(允许省略public、final修饰符),所有的抽象方法的访问权限一定都是public(允许省略public、abstract修饰符),例如:
interface Test{
public final int MAX = 100; // 等价写法:int MAX = 100;
public abstract void add(); // 等价写法:void add();
public abstract float getSum(float x,float y);
}
示例:
test.java
public interface Test {
int MAX= 100; //常量
int getSum(int x); //抽象方法
}
3)接口的使用
类通过使用关键字implements声明自己实现一个或多个接口,如果实现多个接口,则用逗号隔开接口名.
class A implements Printable,Addable
class Dog extends Animal implements Eatable,Sleepable
如果一个类实现了某个接口,那么这个类必须重写该接口的所有方法。
示例:
创建类Tom Bob实现test这个接口
Tom.java
public class Tom implements Test {
@Override
public int getSum(int x) { //重写了getSum这个方法
int sum = 0;
for (int i = 1; i <= x; i++) {
sum = sum + i;
}
return sum;
}
}
Bob.java
public class Bob implements Test {
@Override
public int getSum(int x) { //重写了getSum这个方法
return 12 + x;
}
}
以上两个类实现了这个接口,但他们实现的方式却不同
在主类中如何来运用它呢?
Demo26.java
public class Demo26 {
public static void main(String[] args) {
Tom tom = new Tom();
Bob bob = new Bob();
System.out.println("tom的计算结果:"+tom.getSum(20));
System.out.println("bob的计算结果:"+bob.getSum(20));
}
}
运行结果 这是最简单的声明了两个接口,然后用两个类来实现这个接口
4)理解接口
接口可以增加很多类都需要具有的功能,不同的类可以实现相同的接口,同一个类也可以实现多个接口。
接口只关心操作,并不关心操作的具体实现
接口的思想在于它可以增加很多类都需要具有的功能,而且实现相同的接口类不一定有继承关系。
接口回调是指可以把实现某一接口的类创建的对象的引用赋给该接口声明的接口变量中,那么该接口变量就可以调用被类重写的接口方法。
示例:
创建接口test
Test.java
public interface Test {
int getSum(int x);
}
Tom 实现这个接口,重写相应的方法
Tom .java
public class Tom implements Test{
@Override
public int getSum(int x) {
int sum = 0;
for(int i=1;i<=x;i++){
sum = sum+i;
}
return sum;
}
}
主类Demo27
public class Demo27 {
public static void main(String[] args) {
Test test; //声明一个接口的变量
Tom tom = new Tom();
test = tom;
System.out.println("test的计算结果:"+test.getSum(20));
}
}
运行结果
接口的多态性
把实现接口的类的实例的引用赋值给接口变量后,该接口变量就可以回调类重写的接口方法。
由接口产生的多态就是指不同的类在实现同一个接口时可能具有不同的实现方式,那么接口变量在回调接口方法时就可能具有多种形态。
示例:
创建一个Bob实现这个接口
Bob.java
public class Bob implements Test{
@Override
public int getSum(int x) {
return 12+x;
}
}
主类中如何来写它呢?
Demo27.java
public class Demo27 {
public static void main(String[] args) {
Test test;
Tom tom = new Tom();
test = tom;
System.out.println("test的计算结果:"+test.getSum(20));
test = new Bob(); //合三为一
System.out.println("test的计算结果:"+test.getSum(20));
}
}
和上转型对象实现的多态是非常相似的,这里只是用到了抽象的最高境界接口还实现,显得更加的纯粹,简单
Abstract类和接口类的比较
接口和abstract类的比较如下:
1.abstract类和接口都可以有abstract方法。
2.接口中只可以有常量,不能有变量;而abstract类中即可以有常量也可以有变量。
3.abstract类中也可以有非abstract方法,接口不可以。
面向接口编程
面向接口去设计程序,可以通过在接口中声明若干个abstract方法,表明这些方法的重要性,方法体的内容细节由实现接口的类去完成。
使用接口进行程序设计的核心思想是使用接口回调,即接口变量存放实现该接口的类的对象的引用,从而接口变量就可以回调类实现的接口方法。