Java菜鸟学习笔记--面向对象篇(十三):interface

来源:互联网 发布:语音识别模块 淘宝 编辑:程序博客网 时间:2024/05/19 19:13

什么是接口?


接口不是类,而是对类的一组需求。

        Java中的接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。 接口的两种含义:一,Java接口,Java语言中存在的结构,有特定的语法和结构;二,一个类所具有的方法的特征集合,是一种逻辑上的抽象。前者叫做“Java接口”,后者叫做“接口”。

       Java接口的方法只能是抽象的和公开的,Java接口不能有构造器,Java接口可以有public,静态的和final属性。

       接口把方法的特征和方法的实现分割开来。这种分割体现在接口常常代表一个角色,它包装与该角色相关的操作和属性,而实现这个接口的类便是扮演这个角色的演员。一个角色由不同的演员来演,而不同的演员之间除了扮演一个共同的角色之外,并不要求其它的共同之处。



与抽象类区别



        Java接口和Java抽象类最大的一个区别,就在于Java抽象类可以提供某些方法的部分实现,而Java接口不可以,这大概就是Java抽象类唯一的优点吧,但这个优点非常有用。如果向一个抽象类里加入一个新的具体方法时,那么它所有的子类都一下子都得到了这个新方法,而Java接口做不到这一点,如果向一个Java接口里加入一个新方法,所有实现这个接口的类就无法成功通过编译了,因为你必须让每一个类都再实现这个方法才行,这显然是Java接口的缺点。

        一个抽象类的实现只能由这个抽象类的子类给出,也就是说,这个实现处在抽象类所定义出的继承的等级结构中,而由于Java语言的单继承性,所以抽象类作为类型定义工具的效能大打折扣。在这一点上,Java接口的优势就出来了,任何一个实现了一个Java接口所规定的方法的类都可以具有这个接口的类型,而一个类可以实现任意多个Java接口,从而这个类就有了多种类型。


语法


定义接口


     使用interface来定义一个接口。接口定义同类的定义类似,也是分为接口的声明和接口体,其中接口体由常量定义和方法定义两部分组成。定义接口的基本格式如下:

[修饰符] interface 接口名 [extends 父接口名列表]{

[public] [static] [final] 常量;
[public] [abstract] 方法;

        }

修饰符:可选,用于指定接口的访问权限,可选值为public。如果省略则使用默认的访问权限。
接口名:必选参数,用于指定接口的名称,接口名必须是合法的Java标识符。一般情况下,要求首字母大写。
extends 父接口名列表:可选参数,用于指定要定义的接口继承于哪个父接口。当使用extends关键字时,父接口名为必选参数。
方法:接口中的方法只有定义而没有被实现。

interface USB{//int a;不能定义变量//接口默认必须是public权限//抽象方法,只能有声明不能有实现public void usbread();public void usbwrite();/*public void print(){System.out.println("sm");}*//*USB.java:10: error: interface methods cannot have bodypublic void print(){                   ^1 error*///接口不能有实现部分的方法}



实现接口

接口在定义后,就可以在类中实现该接口。在类中实现接口可以使用关键字implements,其基本格式如下:

[修饰符] class <类名> [extends 父类名] [implements 接口列表]{
}
修饰符:可选参数,用于指定类的访问权限,可选值为public、abstract和final。
类名:必选参数,用于指定类的名称,类名必须是合法的Java标识符。一般情况下,要求首字母大写。
extends 父类名:可选参数,用于指定要定义的类继承于哪个父类。当使用extends关键字时,父类名为必选参数。
implements 接口列表:可选参数,用于指定该类实现的是哪些接口。当使用implements关键字时,接口列表为必选参数。当接口列表中存在多个接口名时,各个接口名之间使用逗号分隔。


//用implements实现多个接口class Phone implements USB,WIFI,GPRS{//用复写实现接口USB的抽象方法public void usbread(){System.out.println("USB Phoen read");}public void usbwrite(){System.out.println("USB Phone write");}//继承了WIFI的抽象方法 open() close(),必须复写实现他们public void wifiopen(){System.out.println("WIIF open");}public void wificlose(){System.out.println("WIFI close");}//3G模块实现public void gprs_open(){System.out.println("GPRS open");}public void gprs_close(){System.out.println("GPRS close");}}


继承接口

在类的继承中,只能做单重继承,而实现接口时,一次则可以实现多个接口,每个接口间使用逗号“,”分隔。
//用PhoneFunction 继承wifi和usb接口//用extends 继承,不是用implementsinterface PhoneFunction extends WIFI,GPRS,USB{//继承了多个接口,也可以在这个增加方法}


接口中方法名冲突


如果出现方法冲突时,则只要实现一个方法就可以了。

interface GPRS{//在WIFI中定义一样的方法声明,然后在同一个类实现回出现什么?public void open();public void close();}
//wifi接口的创建interface WIFI{//在GPRS中定义一样的方法,然后在实现中怎么办?public void open();public void close();}
//用implements实现多个接口class Phone implements USB,WIFI,GPRS{//用复写实现接口USB的抽象方法public void usbread(){System.out.println("USB Phoen read");}public void usbwrite(){System.out.println("USB Phone write");}//继承两个接口中的相同方法声明public void open(){System.out.println("WIF GPRS open");}public void close(){System.out.println("WIFI GPRS close");}}
public class Test{public static void main(String[] args){//1.用Phone实现多个接口(接口WIFI,USB)Phone iphone=new Phone();//通过向上转型WIFI wifi=iphone;wifi.open();wifi.close();GPRS gprs=iphone;gprs.open();gprs.close();/*输出:WIF GPRS openWIFI GPRS closeWIF GPRS openWIFI GPRS close*///同一个方法实现,无论怎么调用都是统一个方法}}

接口中常量冲突

如果出现常量或方法名冲突的情况,解决该问题时,如果常量冲突,则需要明确指定常量的接口,这可以通过“接口名.常量”实现。

package me.confict;interface GPRS{//我们定义名字为ersion的常量//定义可以不写 public static final,因为默认会自动添加public static final double VERSION=4.03;public void justtest();}//wifi接口的创建interface WIFI{//我们定义相同的常量public static final double VERSION=2.3;public void say();}//然后我们通过一个class把两个接口实现了class TestConflict implements GPRS,WIFI{public void say(){System.out.println("这是用于测试冲突的常量");}public void justtest(){//请问这应该输出哪个接口的VERSION?//咱先编译试试//System.out.println("VERSION= "+VERSION);/*然后编译出错:yg@Gander:~/Desktop/code$ javac -d . TestConflict.java TestConflict.java:32: error: reference to VERSION is ambiguous, both variable VERSION in GPRS and variable VERSION in WIFI matchSystem.out.println("VERSION= "+VERSION);       ^1 error*///reference to VERSION is ambiguous,编译器指出在编译时候,引用不明确,模糊不清,存在歧意。//咱修改方法,然后用指明的指出这个常量属于哪一个接口System.out.println("WIFI.VERSION= "+WIFI.VERSION);System.out.println("GPRS.VERSION= "+GPRS.VERSION);}//完了当然要用main()测试咯public static void main(String[] args){TestConflict coco=new TestConflict();coco.justtest();//编译无错,运行/*输出:yg@Gander:~/Desktop/code$ java me.confict.TestConflict WIFI.VERSION= 2.3GPRS.VERSION= 4.03*///这回是不是可以了输出咱想要的变量}}




作者:YangGan
出处:http://blog.csdn.net/incyanggan
本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名Yanggan(包含链接).


原创粉丝点击