之前已经详细说明了接口,抽象类,普通类以及实例的作用了,该文章用现实中的例子来更好地了解这些关系,但是实际编码中,好处究竟在哪里呢?

接口,继承父类等设计,都是为了面向抽象编程,之前的博客也有说明面向抽象编程有什么好处。其实无非就是解耦,而解耦的目的就是为了代码扩展性更强。在这里就举其他一些例子来更好地证明通过接口与父类来面向编程的好处

一:回调接口

在接触了java的web开发,或者其他编程语言开发,都会接触到“回调接口”。那么回调接口是如何实现的呢?其实原理很简单,就是利用了接口,通过面向接口的方法,把接口方法留给其他人自定义。通过回调接口,不仅可以提高代码的可扩展性,还可以实现两个类之间的通信

//这里实现的是Person执行process方法时,会执行自定义的回调方法,输出“自定义的回调逻辑”
//这里通常是传入一个类,然后调用一个类的实例方法,但是如果需求是方法逻辑需要后期自定义来实现
//就不适合直接传入一个实例对象,而应该传入一个接口方法,让其他人自定义接口方法即可
public class MainApp{
    public static void main(Stirng args[]){
    Person person = new Person(()->{System.out.print("自定义的回调逻辑")});
    person.process();
}
}


public class Person {
    Do do;
    public Person(Do do){
    this.do = do
}

    public void process(){
    System.out.print("执行默认逻辑")
    do.do()//这里调用的是接口方法do(),实际逻辑是由Perso构造函数中的入参来决定  
}

}

public interface Do(){
   void do();

}

二:通过继承父类,让子类实现自定义的功能

这个用途Spring框架运用得淋漓尽致,通常Spring框架会留下一个可扩展的父类(或接口),然后可以自定义子类去继承,然后自定义组件(如自定义拦截器)当容器初始化时,就会去扫描相应的配置类,把自定义组件加入到容器中,即使加入了自定义组件,但是框架中的逻辑是不需要改变的(这就是面向抽象编程的好处)

//简单模拟一下spring调用自定义组件的逻辑

public class MainApp(){

public static void main(String args[]){
    1.扫描配置类,把自定义组件加入到容器中,假设用集合interceptors存储所有拦截器(代码省略)
    (这就是我们通常需要通过配置类手动注册自定义组件到容器中的原因)
    
    2.拿到interceptors,遍历每一个对象,向上转型为接口,调用接口方法
    for(HandleInterceptor interceptor: interceptors){
        intercepter.preHandle()
}


}
}

其实,所谓回调接口就相当于模板方法模式中的钩子方法。所谓模板方法模式,通俗来讲就是一切琐碎,通用的方法或逻辑已经给你实现了,需要自定义的一部分则留给其他人去实现。而自定义的这一部分,或者这一个方法,则叫做钩子方法。我们可以通过回调接口,或者抽象方法等都可以来实现模板方法模式,提供程序的可扩展性。