Java基础之(二十)接口

说明
现实中也有很多接口的实例,比如说USB接口、串口电脑硬盘,Serial ATA委员会指定了Serial ATA 2.0规范,这种规范就是接口。Serial ATA委员会不负责生产硬盘,只是指定通用的规范。

希捷、日立、三星等生产厂家会按照规范生产符合接口的硬盘,这些硬盘就可以实现通用化,如果正在用一块160G日立的串口硬盘,现在要升级了,可以购买一块320G的希捷串口硬盘,安装上去就可以继续使用了。

下面的代码可以模拟Serial ATA委员会定义以下串口硬盘接口:

//串行硬盘接口
public interface SataHdd{
    //连接线的数量
    public static final int CONNECT_LINE=4;
    //写数据
    public void writeData(String data);
    //读数据
    public String readData();
}

接口定义了某一批类所需要遵守的规则。

接口的概念

接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。

接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。

除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。

接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在Java中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

接口的声明

接口的声明语法格式如下:

[修饰符] interface 接口名称 [extends 父接口1,父接口2...] {
        // 声明变量
        // 抽象方法
}

Interface关键字用来声明一个接口。下面是接口声明的一个简单例子。

public interface USB{
    //连接线的数量
    public static final int CONNECT_LINE=4;
    //写数据
    public void writeData();
    //读数据
    public String readData();
}

从上面的程序中看,接口有其自身的一些特性,归纳如下。

  1. 接口中只能定义抽象方法,这些方法默认为 public abstract 的,因而在声明方法时可以省略这些修饰符。试图在接口中定义实例变量、非抽象的实例方法及静态方法,都是非法的。

  2. 接口中没有构造方法,不能被实例化。

  3. 接口中的方法都是public权限

  4. 接口中声明的成员变量默认都是 public static final 的,必须显示的初始化。因而在常量声明时可以省略这些修饰符。

  5. 接口是隐式抽象的。声明一个接口,不需要使用abstract关键字

接口的实现

当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。

类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。

实现一个接口的语法,可以使用这个公式:

... implements 接口名称[, 其他接口, 其他接口..., ...] ...

下面代码定义了一个USBPhone类:

interface USB{
    //连接线的数量
    public static final int CONNECT_LINE=4;
    //写数据
    public void writeData();
    //读数据
    public void readData();
}
class USBPhone implements USB{
     public void writeData(){
    System.out.println("USBPhone writeDate");
    }

     public void readData(){
        System.out.println("USBPhone readDate");
    }
}
class Test{
    public static void main(String[] args){
    USBPhone usbPhone = new USBPhone();
    USB usb = usbPhone;
    usb.writeData();
    usb.readData();
    }
}
输出结果:
USBPhone writeDate
USBPhone readDate

对于接口来讲,一个类可以实现多个接口。

比如现实世界中,手机可以通过数据线连接电脑,也可以通过wifi来连接电脑,也可以通过蓝牙连接电脑,因此我们可以说这部手机既支持USB标准,也支持蓝牙标准。

看下面的例子:

interface USB{
    //连接线的数量
    public static final int CONNECT_LINE=4;
    //写数据
    public void writeData();
    //读数据
    public void readData();
}
interface BlueTooth{
    //打开蓝牙
    public void open();
    //关闭蓝牙
    public void close();
}
class Phone implements USB,BlueTooth{
     public void writeData(){
        System.out.println("USBPhone writeDate");
    }

     public void readData(){
        System.out.println("USBPhone readDate");
    }

    public void open(){
        System.out.println("BlueTooth open");
    }

    public void close(){
        System.out.println("BlueTooth close");
    }
}
class Test{
    public static void main(String[] args){
    Phone phone = new Phone();

    USB usb = phone;
    usb.writeData();
    usb.readData();

    BlueTooth bt = phone;
    bt.open();
    bt.close();
    }
}
输出结果:
USBPhone writeDate
USBPhone readDate
BlueTooth open
BlueTooth close

重写接口中声明的方法时,需要注意以下规则:

  • 类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出该强制性异常。

  • 类在重写方法时要保持一致的方法名,并且应该保持相同或者相兼容的返回值类型。

  • 如果实现接口的类是抽象类,那么就没必要实现该接口的方法。

    在实现接口的时候,也要注意一些规则:

  • 一个类可以同时实现多个接口。

  • 一个类只能继承一个类,但是能实现多个接口。

接口的继承

一个接口能继承另一个接口,和类之间的继承方式比较相似,但和类的单继承不同的是,接口完全支持多继承,即一个接口可以有多个直接父接口。
接口的继承使用extends关键字,子接口继承父接口的所有抽象方法、常量Field、内部类和枚举类。

例如:

interface A{
    int PROP_A = 5;
    public void funA();
}

interface B{
    int PROP_B = 6;
    public void funB();
}

interface C extends A,B{
    int PROP_C = 7;
    public void funC();
}

public class TestInterfaceExtends 
{
    public static void main(String[] args)
    {
        System.out.println(C.PROP_A);
        System.out.println(C.PROP_B);
        System.out.println(C.PROP_C);
    }
}
输出结果:
5
6
7

上面的程序中C继承了A和B,所以C获得了他们的常量Field。

接口的使用

接口的使用与类的使用有些不同。在需要使用类的地方,会直接使用new关键字来构建一个类的实例,但接口不可以这样使用,因为接口不能直接使用 new 关键字来构建实例。

接口必须通过类来实现(implements)它的抽象方法,然后再实例化类。类实现接口的关键字为implements。

如果一个类不能实现该接口的所有抽象方法,那么这个类必须被定义为抽象方法。

不允许创建接口的实例,但允许定义接口类型的引用变量,该变量指向了实现接口的类的实例。

一个类只能继承一个父类,但却可以实现多个接口。

实现接口的格式如下:

修饰符 class 类名 extends 父类 implements 多个接口 {
   // 实现方法
}

下面看一个例子:

interface Edible{
    public abstract String howToEat();
}

class Animal{

}

class Chicken extends Animal implements Edible{
    @Override
    public String howToEat() {
        // TODO Auto-generated method stub
        return "Chicken:Fry it";
    }
}
public class Test {
    public static void main(String[] args)
    {
        Chicken ch = new Chicken();
        System.out.println(ch.howToEat());
    }

}
输出结果:
Chicken:Fry it"

抽象类实现接口的情况:

interface Edible{
    public abstract String howToEat();
}

abstract class Fruit implements Edible{

}

class Apple extends Fruit{
    public String howToEat(){
        return "Apple:Make Apple ciser";
    }
}
public class Test {
    public static void main(String[] args)
    {
        Apple a = new Apple();
        System.out.println(a.howToEat());
    }

}
输出结果:
Apple:Make Apple ciser

接口的应用

为什么使用接口?

大型项目开发中,可能需要从继承链的中间插入一个类,让它的子类具备某些功能而不影响它们的父类。例如 A -> B -> C -> D -> E,A 是祖先类,如果需要为C、D、E类添加某些通用的功能,最简单的方法是让C类再继承另外一个类。但是问题来了,Java 是一种单继承的语言,不能再让C继承另外一个父类了,只到移动到继承链的最顶端,让A再继承一个父类。这样一来,对C、D、E类的修改,影响到了整个继承链,不具备可插入性的设计。

接口是可插入性的保证。在一个继承链中的任何一个类都可以实现一个接口,这个接口会影响到此类的所有子类,但不会影响到此类的任何父类。此类将不得不实现这个接口所规定的方法,而子类可以从此类自动继承这些方法,这时候,这些子类具有了可插入性。

我们关心的不是哪一个具体的类,而是这个类是否实现了我们需要的接口。

标记接口

最常用的继承接口是没有包含任何方法的接口。

标识接口是没有任何方法和属性的接口.它仅仅表明它的类属于一个特定的类型,供其他代码来测试允许做一些事情。

标识接口作用:简单形象的说就是给某个对象打个标(盖个戳),使对象拥有某个或某些特权。

例如:java.awt.event包中的MouseListener接口继承的java.util.EventListener接口定义如下:

package java.util;
public interface EventListener
{}

没有任何方法的接口被称为标记接口。标记接口主要用于以下两种目的:

  • 建立一个公共的父接口:

    正如EventListener接口,这是由几十个其他接口扩展的Java API,你可以使用一个标记接口来建立一组接口的父接口。例如:当一个接口继承了EventListener接口,Java虚拟机(JVM)就知道该接口将要被用于一个事件的代理方案。

  • 向一个类添加数据类型:

    这种情况是标记接口最初的目的,实现标记接口的类不需要定义任何接口方法(因为标记接口根本就没有方法),但是该类通过多态性变成一个接口类型。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值