接口

接口

抽象类是从多个类中抽象出来的模板,如果将这种抽象进行的更加彻底,则可以提炼出一种更特殊的“抽象类–接口”。接口里不能包含普通的方法,接口里的所有方法都是抽象方法
接口定义的是多个类共同的公共行为规范,这些行为是与外界交流的通道,这就意味着接口里通常是定义一组公用方法。

和类不同,定义接口使用的是关键字interface.
定义接口的基本语法如下:

[修饰符] interface 接口名 extends 父接口1, 父接口2...
{
    零到多个常量定义...
    零到多个抽象方法定义...
    零到多个内部类,接口,枚举定义...
    零到多个默认方法或类方法定义...
}

修饰符可以是public或者省略,如果省略则默认采用包权限访问控制符
接口只能继承接口,不能继承类
由于接口定义的是一种规范,因此接口里不能包含构造器和初始化块定义。接口里可以包含成员变量(只能是静态常量),方法(只能是抽象实例方法,类方法或默认方法),内部类。
在接口内定义成员变量的时候,系统自动为其添加public static final修饰
在接口内定义普通方法的时候,系统自动为其增加public abstract修饰
接口里的普通方法不能有方法体;但是类方法和默认方法都必须有方法体

下面我们来看一个例子

package chen;

public interface Output {
    //接口里面定义的成员变量只能是常量
    int MAX_CACHE_LINE = 50;
    //接口里定义的普通方法只能是public的抽象方法
    void out();
    void getData(String msg);
    //在接口里面定义默认方法,需要使用default修饰
    default void print(String... msgs)
    {
        for (String msg: msgs){
            System.out.println(msg);
        }
    }
    default void test()
    {
        System.out.println("默认的test()方法");
    }
    //在接口中定义类方法,需要static修饰
    static String staticTest()
    {
        return "接口的类方法";
    }
}

上面定义了一个Output接口,这个接口包含一个成员变量MAX_CACHE_LINE。除此之外,这个接口还定义了两个普通方法:表示取得数据的getData()方法和表示输出的out()方法。这就定义了Output接口的规范:只要某个类能取得数据,并可以将数据输出,那么它就是一个输出设备。至于实现的细节这里暂时不关心。
接口中的默认方法和类方法都默认是public的,默认方法需要用接口的实现类的实例来调用,而类方法可以直接使用接口来调用。

package min;

public class OutputFieldTest {
    public static void main(String[] args)
    {
        //访问另一个包中的Output接口的成员变量
        System.out.println(chen.Output.MAX_CACHE_LINE);
        //下面语句将引发“为final变量赋值”的编译异常
        //chen.Output.MAX_CACHE_LINE = 20;
        //使用接口来调用类方法
        System.out.println(chen.Output.staticTest());
    }
}

从上面的程序我们可以看到,虽然这个类和接口处于不同的包下,但是可以访问接口的MAX_CACHE_LINE常量,说明其为public访问限定的,而且可以通过接口来访问,表明这个成员变量是一个类变量。而且很明显,这个变量是final的

接口的继承

接口的继承和类继承不一样,接口完全支持多继承,即一个接口可以有多个直接父接口。
和类继承相似,子接口扩展某个父接口时,会获得父接口里定义的所有抽象方法和常量。

package the6;

interface interfaceA{
    int PROP_A = 5;
    void testA();
}
interface interfaceB{
    int PROP_B = 6;
    void testB();
}

interface interfaceC extends interfaceA, interfaceB
{
    int PROP_C = 7;
    void testC();
}

public class InterfaceExtendsTest {
    public static void main(String[] args)
    {
        System.out.println(interfaceC.PROP_A);
        System.out.println(interfaceC.PROP_B);
        System.out.println(interfaceC.PROP_C);
    }
}

上面的程序中的interfaceC接口继承了interfaceA和interfaceB,所以interfaceC获得了它们的常量。

使用接口

接口的主要用途:
1. 定义变量,也可以用于强制类型转换。
2. 调用接口中定义的常量。
3. 被其他类实现。

一个类可以实现一个或者多个接口。
继承使用extends关键字,实现使用implements关键字,语法如下:

[修饰符] class 类名 extends 父类 implements 接口1, 接口2...
{
    类体部分
}

一个类实现了一个或多个接口后,必须重写全部的抽象方法。

package the6;

import chen.Output;

//定义一个product接口
interface Product
{
    int getProduceTime();
}
//让Printer类实现Output和Product接口
public class Printer implements Output, Product {
    private String[] printData = new String[MAX_CACHE_LINE];
    private int dataNum = 0;   //用以记录当前需打印的作业数

    @Override
    public int getProduceTime() {
        return 45;
    }                               

    @Override
    public void out() {
        //只要还有作业,就继续打印
        while(dataNum > 0)
        {
            System.out.println("打印机打印:"+printData[0]);
            //把作业队列整体前移一位,并将剩余的作业数减1
            System.arraycopy(printData, 1, printData, 0, --dataNum);
        }
    }

    @Override
    public void getData(String msg) {
        if (dataNum >= MAX_CACHE_LINE){
            System.out.println("输出队列已买,添加失效");
        }
        else{
            printData[dataNum++] = msg;
        }
    }

    public static void main(String[] args){
        //创建一个Printer对象,当成Output使用
        Output o = new Printer();
        o.getData("打印一");
        o.getData("打印二");
        o.out();
        o.getData("打印三");
        o.getData("打印四");
        o.out();
        //调用Output接口中定义的默认方法
        o.print("调用Output接口中定义的默认方法","123","456","789");
        o.test();
        //创建一个Printer对象,当成Product使用
        Product p = new Printer();
        System.out.println(p.getProduceTime());
        //所有接口类型的引用变量都可直接赋给Object类型的变量
        Object obj = p;
    }

}

我们可以看到,Printer类实现了Output接口和Product接口。
因此Printer对象既可以直接赋给Output变量,也可以直接赋给Product变量,这就是java提供的模拟多继承。

接口和抽象类

相同点:
  1. 接口和抽象类都不能被实例化。他们都用于被其他类实现和继承。
  2. 接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。
不同点:
  1. 接口只能包含抽象方法和默认方法,不包含普通方法;抽象类可包含普通方法
  2. 接口不能定义静态方法;抽象类可以定义静态方法。
  3. 接口里只能定义静态常量;抽象类不受此限制。
  4. 接口不含构造器;抽象类可含构造器但是不用于创建对象。
  5. 接口不含初始化块;抽象类可以含有初始化块。
  6. 一个类可以同时实现多个接口,弥补了java单继承的不足。

面向接口编程

接口体现的是一种规范和实现分离的设计哲学,充分利用接口可以极好地降低程序各个模块之间的耦合,从而提高系统的可扩展性和可维护性。

简单工厂模式
命令模式
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值