Java中的接口

一、概念

接口:就像类与类之间的一种协议,只需要知道某个类实现的某个接口, 那么,他就可以通过调用接口里面的方法来指向这个类的实现。

二、特性

(1)使用interface标注

(2)完全抽象

(3)属性域必须是public final static(这个是编译器自动转换的)

(4)方法必须是public

(5)向上转型,为父类指向子类对象提供途径,同时也使得java拥有多态这个特性

(6)不可以实例化

(7)接口可以多重实现

package com.ray.ch07;  

public class Test {  
    public void tune(Instrument instrument) {  
        instrument.Play();  
    }  

    public void tune(Instrument[] instruments) {  
        for (int i = 0; i < instruments.length; i++) {  
            tune(instruments[i]);  
        }  
    }  

    public static void main(String[] args) {  
        Test test = new Test();  
        // Instrument instrument = new Instrument();//error  
        Instrument wind = new Wind();  
        Instrument bass = new Bass();  
        Instrument[] instruments = { wind, bass };  
        test.tune(instruments);  
        System.out.println(Instrument.id);// id是static  
    }  
}  

interface Instrument {  
    // private int id=0;//error  
    // private void Play();//error  

    int id = 0;  

    void Play();  
}  

class Wind implements Instrument {  

    @Override  
    public void Play() {  
        // id=2;//The final field Instrument.id cannot be assigned  
        System.out.println(id);  
        System.out.println("wind play");  
    }  
}  

class Bass implements Instrument {  
    @Override  
    public void Play() {  
        System.out.println("bass play");  
    }  
}  

输出:

0
wind play
bass play
0

从上面的代码可以看见:

1.接口是不可以new 的

2.子类必须实现接口的方法

3.通过向上转型,以Instrument为类型定义的wind和bass,也可以调用play方法,而且运行时自动识别应该绑定那个play方法

4.由于wind和bass必须重写play,因此play一定是public,因为wind和bass不是继承Instrument

5.我们通过打印Instrument里面的id,知道id一定是static,因为可以直接使用Instrument调用,而不需要new

6.通过在实现类wind里面修改id,就可以看到他的提示,提示id是final的。

三、接口解耦

我们建立一个通用接口,然后两个基类分别实现接口,然后通过向上转型,实现多态,使得TestObjectInterface这个父类指向各个不同的子类的,从而调用不同子类的方法。

在这里我们再扩展一下,其实是运用了策略设计模式。TestObjectInterface一直是执行算法里面固定的部分,然后通过不同类型的传入,分别执行不同的实现。

package com.ray.ch07;  

public class Test {  

    public static void test(TestObjectInterface testObjectInterface) {  
        testObjectInterface.test();  
    }  

    public static void main(String[] args) {  
        test(new Wind());  
        test(new Bass());  
        test(new BMW());  
        test(new Audi());  
    }  
}  

interface TestObjectInterface {  
    void test();  
}  

class Instrument implements TestObjectInterface {  
    @Override  
    public void test() {  
        System.out.println("Instrument test");  
    }  
}  

class Wind extends Instrument {  
    @Override  
    public void test() {  
        System.out.println("Wind test");  
    }  
}  

class Bass extends Instrument {  
    @Override  
    public void test() {  
        System.out.println("Bass test");  
    }  
}  

class Vehicle implements TestObjectInterface {  
    @Override  
    public void test() {  
        System.out.println("Vehicle test");  
    }  
}  

class BMW extends Vehicle {  
    @Override  
    public void test() {  
        System.out.println("BMW test");  
    }  
}  

class Audi extends Vehicle {  
    @Override  
    public void test() {  
        System.out.println("Audi test");  
    }  
}  

四、多重接口

使用继承,我们只是继承某一类,只能够一种向上转型,但是在接口的使用方面,可以实现多个接口,然后实现多种的向上转型。

package com.ray.ch07;  

public class Test {  

    public static void testSwim(CanSwim canSwim) {  
        canSwim.swim();  
    }  

    public static void testEat(CanEat canEat) {  
        canEat.eat();  
    }  

    public static void testRun(CanRun canRun) {  
        canRun.run();  
    }  

    public static void main(String[] args) {  
        Person person = new Person();  
        testSwim(person);//向上转型为CanSwim  
        testEat(person);//向上转型为CanEat  
        testRun(person);//向上转型为CanRun  
        Fish fish = new Fish();  
        testSwim(fish);//  
        // testEat(fish);//error,因为没有实现接口,不能向上转型  
        // testRun(fish);//error,因为没有实现接口,不能向上转型  
    }  
}  

interface CanRun {  
    void run();  
}  

interface CanSwim {  
    void swim();  
}  

interface CanEat {  
    void eat();  
}  

class Person implements CanEat, CanRun, CanSwim {  

    @Override  
    public void swim() {  
        System.out.println("i can swim");  
    }  

    @Override  
    public void run() {  
        System.out.println("i can run");  
    }  

    @Override  
    public void eat() {  
        System.out.println("i can eat");  
    }  

}  

class Fish implements CanSwim {  

    @Override  
    public void swim() {  
        System.out.println("i can swim");  
    }  
}  

解释一下上面的代码:

1.建立了三个接口:会游泳,会跑,会吃

2.建立一个Person类,实现上面三个接口

3.建立一个Fish类,只是实现游泳的接口

4.然后在测试代码里面使用策略设计模式,测试一下三种技能

在代码里,Person 分别向上转型为CanRun、CanSwim、CanEat这三种类型,这样大大增强代码的灵活性,要不然我们就必须在测试代码方面增加代码,才能够完整测试。而且也不利于代码的复用,假如CanSwim这个不是接口,他变成了基类,但是他的实现可能对于Person或者Fish来说都是不合适的,而且代码可能歧义,但是现在是接口,只是一种协议,说明子类只是具备某种功能,而这个功能怎么实现,具体需要根据子类的实现来说,这样代码更能够广泛的复用。

五、接口与工厂设计模式

接口是实现多重继承的途径,生成遵循某个接口协议的对象的典型方式是工厂设计模式。

这种设计模式使得接口与实现完全分开。

package com.ray.ch07;  

interface Service {  
    void doSomeThing();  
}  

interface ServiceFactory {  
    Service getService();  
}  

class ServiceImpl implements Service {  

    @Override  
    public void doSomeThing() {  

    }  
}  

class ServiceFactoryImpl implements ServiceFactory {  

    @Override  
    public Service getService() {  
        // TODO Auto-generated method stub  
        return null;  
    }  
}  

public class Test {  
    public static void test(ServiceFactory factory) {  
        Service service = factory.getService();  
        service.doSomeThing();  
    }  

    public static void main(String[] args) {  
        test(new ServiceFactoryImpl());  
    }  
}  

从上面的代码看出,我们只是在最后一步new的时候,才把实现类放进去,其他的代码基本以接口来实现,从而把接口与实现完全分离,这样有利于Test这个代码的重复使用。

那么,怎么使用呢?

我们下面给出例子:(就是有多个Service的时候,Test就可以重复使用了)

package com.ray.ch07;  

interface Service {  
    void doSomeThing();  
}  

interface ServiceFactory {  
    Service getService();  
}  

class ServiceImpl implements Service {  

    @Override  
    public void doSomeThing() {  

    }  
}  

class ServiceFactoryImpl implements ServiceFactory {  

    @Override  
    public Service getService() {  
        // TODO Auto-generated method stub  
        return null;  
    }  
}  

class ServiceImpl2 implements Service {  

    @Override  
    public void doSomeThing() {  

    }  
}  

class ServiceFactoryImpl2 implements ServiceFactory {  

    @Override  
    public Service getService() {  
        // TODO Auto-generated method stub  
        return null;  
    }  
}  

public class Test {  
    public static void test(ServiceFactory factory) {  
        Service service = factory.getService();  
        service.doSomeThing();  
    }  

    public static void main(String[] args) {  
        test(new ServiceFactoryImpl());  
        test(new ServiceFactoryImpl2());  
    }  
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值