一、基本概念 接口(Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合。接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。 如果一个类只由抽象方法和全局常量组成,那么这种情况下不会将其定义为一个抽象类。只会定义为一个接口,所以接口严格的来讲属于一个特殊的类,而这个类里面只有抽象方法和全局常量,就连构造方法也没有。 范例:定义一个接口 interface A{//定义一个接口 public static final String MSG = 'hello';//全局常量 public abstract void print();//抽象方法}
二、接口的使用 1、由于接口里面存在抽象方法,所以接口对象不能直接使用关键字new进行实例化。接口的使用原则如下: 范例:
运行结果: 接口A的抽象方法print()接口B的抽象方法get()
以上的代码实例化了X类的对象,由于X类是A和B的子类,那么X类的对象可以变为A接口或者B接口对象。我们把测试主类代码改一下:
运行结果: 接口B的抽象方法get()
好,没任何问题,我们再来做个验证:
运行结果: 接口B的抽象方法get()truetrue
我们发现,从定义结构来讲,A和B两个接口没有任何直接联系,但这两个接口却拥有同一个子类。我们不要被类型和名称所迷惑,因为实例化的是X子类,而这个类对象属于B类的对象,所以以上代码可行,只不过从代码的编写规范来讲,并不是很好。 2、对于子类而言,除了实现接口外,还可以继承抽象类。若既要继承抽象类,同时还要实现接口的话,使用一下语法格式:
范例: interface A{//定义一个接口A public static final String MSG = 'hello';//全局常量 public abstract void print();//抽象方法}interface B{//定义一个接口B public abstract void get();}abstract class C{//定义一个抽象类C public abstract void change();}class X extends C implements A,B{//X类继承C类,并实现了A和B两个接口 @Override public void print() { System.out.println('接口A的抽象方法print()'); } @Override public void get() { System.out.println('接口B的抽象方法get()'); } @Override public void change() { System.out.println('抽象类C的抽象方法change()'); }}
对于接口,里面的组成只有抽象方法和全局常量,所以很多时候为了书写简单,可以不用写public abstract 或者public static final。并且,接口中的访问权限只有一种:public,即:定义接口方法和全局常量的时候就算没有写上public,那么最终的访问权限也是public,注意不是default。以下两种写法是完全等价的:
等价于 interface A{ String MSG = 'hello'; void print();}
但是,这样会不会带来什么问题呢?如果子类子类中的覆写方法也不是public,我们来看:
运行结果: Exception in thread 'main' java.lang.IllegalAccessError: com.wz.interfacedemo.X.print()V at com.wz.interfacedemo.TestDemo.main(TestDemo.java:22)
这是因为接口中默认是public修饰,若子类中没用public修饰,则访问权限变严格了,给子类分配的是更低的访问权限。所以,在定义接口的时候强烈建议在抽象方法前加上public ,子类也加上:
3、在Java中,一个抽象类只能继承一个抽象类,但一个接口却可以使用extends关键字同时继承多个接口(但接口不能继承抽象类)。 范例: interface A{ public void funA();}interface B{ public void funB();}//C接口同时继承了A和B两个接口interface C extends A,B{//使用的是extends public void funC();}class X implements C{ @Override public void funA() { } @Override public void funB() { } @Override public void funC() { }}
由此可见,从继承关系来说接口的限制比抽象类少: 4、从接口的概念上来讲,接口只能由抽象方法和全局常量组成,但是内部结构是不受概念限制的,正如抽象类中可以定义抽象内部类一样,在接口中也可以定义普通内部类、抽象内部类和内部接口(但从实际的开发来讲,用户自己去定义内部抽象类或内部接口的时候是比较少见的),范例如下,在接口中定义一个抽象内部类:
在接口中如果使用了static去定义一个内接口,它表示一个外部接口: interface A{ public void funA(); static interface B{//使用了static,是一个外部接口 public void funB(); }}class X implements A.B{ @Override public void funB() { }}
三、接口的实际应用(标准定义) 在日常的生活之中,接口这一名词经常听到的,例如:USB接口、打印接口、充电接口等等。 如果要进行开发,要先开发出USB接口标准,然后设备厂商才可以设计出USB设备。 现在假设每一个USB设备只有两个功能:安装驱动程序、工作。
在电脑上应用此接口: class Computer { public void plugin(USB usb) { usb.install() ; usb.work() ; }}
定义USB设备—手机:
定义USB设备—打印机: class Print implements USB { public void install() { System.out.println('安装打印机驱动程序。') ; } public void work() { System.out.println('进行文件打印。') ; }}
定义USB设备—MP3:
测试主类: public class TestDemo { public static void main(String args[]) { Computer c = new Computer() ; c.plugin(new Phone()) ; c.plugin(new Print()) ; c.plugin(new MP3()); }}
运行结果:
可以看出,不管有多少个USB接口的子类,都可以在电脑上使用。 未完待续。。。 |
|