【Java】Interface接口的理解和运用

by img Microanswer 创建时间:Jun 11, 2019 1:51:03 PM 

标签: java 接口 interface 回调



重要声明:本文章仅仅代表了作者个人对此观点的理解和表述。读者请查阅时持自己的意见进行讨论。

1、前言

学习Java的同学们都必然会逃不过学习接口这一部分的知识。在学习过程中,难免会遇到一些难点或疑问。为了帮助大家更好的理解接口相关知识,希望这篇文章能帮到一些同学对接口有彻底的理解。

2、入门

先来看一下接口的面貌,下面建立了一个打印接口,实现这个接口需要实现其打印方法:

// 打印接口。
public interface Printer {
    
    // 需要被实现的打印方法。
    void doPrint();
    
}

// Microanswer品牌的打印机,实现这个接口:
public class MicroanswerPrinter implements Printer{
    
    // 实现打印机具体的打印方式。
    public void doPrint() {
        System.out.println("打印...");
    }
}

也许大家学完了接口之后,对接口的理解就是:使用interface声明,任何实现了某个接口的类都必须实现该接口中所有的方法。不得不承认,这的的确确是接口开发的规范,而且也是必须做到这一点的。

但是,疑问点往往不是这么一套限定的开发规则,而是:这东西写起来复杂,看起来扯蛋,想起来还感觉多余,但为什么它又占据了书本中不小的篇幅,为什么大佬们的程序里接口处处可见,难道就是为了彰显自己的技术过硬吗?

针对这些,不得不对接口有个更加简单的、不同于书面教材的解释来解答了。

3、变通

如果一味的将interface直接翻译成接口,虽然它的意思的确是接口,但是个人认为这样给初学者来听还是有点不妥!如果换一种理解方式,可能会稍显简单:

我这样说:interface是一本规则书,如果有某类想要使用,不好意思,请按我书里的规定,实现每一条定律。

结合场景:

公司老总要求生产一台打印机,但是不知道怎么具体去实现,可需要些什么功能,老总倒是心知肚明得很,老总就写了一个说明书,叫下面的员工都按照这说明书上的功能去实现,

如上,接口往往开发人员要写的,而是设计这个产品的人需要什么功能而定义出来的,你不用为了特意写某个类而去为这个类写一个接口,应该是为某个接口而去写这个类。老总定义的这个接口,下面的人只要实现就可以了。这可以说是接口存在的理由之一

另一个场景:

小码想开发一个计数器,可以指定要计数多少,每秒钟计数加1,当到达指定计数值的时候,就会发出提示。小码为难了,因为小码想:“计数到了之后,要提示给别人,但是我要怎么提示呢?由于我不知道人家的类是要怎么去接受消息,也就没法推给别人,我为这个功能为难了好久!”。

这样简单的应用场景,或许你会说,这个接口有什么关系,没有接口也能实现。的确可以不依赖接口,但如果加入接口,会使程序更加灵活。

首先我们不能一味的去迎合别人的程序有哪些方法,而且你在绝大多数情况下,都是不知道别人有什么方法的,为了保证你的程序的原子性,绝对不能介入别人的程序的逻辑。既然是我开发的计数器,别人要使用,你要想:应该别人去迎合我的程序,而不是我去迎合别人。有时候,甚至在同一个程序里不同的功能模块,你也需要这样的想法。

4、应用

这里讲述了接口最常用的场景的实现方案,就拿上面的计数器来说,咱们可以很轻松的写出下面的代码:

public class Counter {
    
    // 调用此方法,传入计数值,开始计数。
    public void start(int count) {
        for(int i = 0; i < count; i++) {
            Thread.sleep(1000); // 每隔1秒计数1次。
        }
        
        // 计数完成,发出提示。
    }
}

简单的示例代码十分好理解,那如何要在计数完成发出提示位置给别人提示呢?这时候,就要把:要别人去迎合我 这种思想拿出来了。

为了让别人迎合我,我制定一个规则,这个规则就是,要接到我计数完成的提示,就得实现我的规则,这里的规则,用接口是一个完美的解释!

public class Counter {
    
    // 调用此方法,传入计数值,开始计数。
    // 接收到什么时候计数完成,请传入定义的规则。
    public void start(int count, CounterEnd counterEnd) {
        for(int i = 0; i < count; i++) {
            Thread.sleep(1000); // 每隔1秒计数1次。
        }
        
        // 计数完成,发出提示。
        counterEnd.onEnd();
    }
    
    // 定义计数完成时提示的规则
    public interface CounterEnd {
        
        // 规则方法。
        void onEnd();
    }
}

我在 start 方法多加了一个参数,CounterEnd, 它正好是由接口定义的。结合咱们之前的认识:实现接口必须实现里面的方法。那么:任何想要使用我的计数器的类, 在调用start方法的时候,它们只要传入一个 按规则 实现好了的类,就可以在这个类里拿到什么时候计数完成的提示了。我作为计数器,不需要关心别人是怎么做的, 别人要用我,自然会关心我应该怎么去整合到他们的代码里。这就优雅的让我不必关心别人的程序逻辑,也能安心的发布我自己的程序了。

例如有下面计数器使用方法:

public static class Test {
    public static void main(String[] args){
      Counter counter = new Counter();
      
      // 由于我希望获得计数器计数完成的提示,所以我要实现计数器提供的 "规则";
      CounterEnd ender = new CounterEnd() {
          public void onEnd() {
              System.out.println("计数器计数完成!");
          }
      };
      
      // 开始计数。
      counter.start(20, ender);
    }
}

5、总结

接口运用,最广泛的地方莫过于本文的场景2的需求了,这其实就是大老们常说的回调,如果对回调需要了解更多,可以参考下一篇文章:

【Java】监听器的理解和开发

全文完, 转载请注明出处。 对你有帮助?不如赞一个吧:
发表评论(发表评论需要登录,你现在还没有登录。)
你需要先登录才可以评论。

评论列表 (0条)