你真正理解接口和实现类之间的关系了吗?面向接口编程真的能解除外部代码耦合吗?

       标题中提到的这两个问题,我相信不仅初学小白难以明白,就连三、五年的老鸟也未必明白。

我们平时在编写代码时候,都明白一个道理:接口是虚的,不能实例化,更不能在没有实现类的情况下调用。这个理解很正确,不过我想问的是,如果你对接口已经配备了实现类,那你调用的方式是哪一种呢?

我们先定义一个接口和一个实现类,代码如下:

// 接口仅声明行为,没有具体实现

public interface Vehicle {
    void drive();  
}

 // 实现类提供具体行为

public class Car implements Vehicle {
    @Override
    public void drive() {
        System.out.println("Car is driving.");
    }
}

第一种方式: 
        Vehicle myCar = new Car();  // 使用接口的实现类
        myCar.drive();  // 调用接口方法

第二种方式: 

       Vehicle myCar = new Vehicle ();  // 使用接口实例
        myCar.drive();  // 调用接口方法

很显然第一种调用方式是常用的正确方式,第二种方式是错误的(想想为什么?)。虽然第一种方式正确,可你调用的是接口实现类的方法,既然这样,那第一种调用方式改写成如下代码正确吗?

       Car  myCar = new Car();  
        myCar.drive();  

       可以说这样改并没有错,也不会编译出错。如果改成这样的赋值变量,似乎那个接口根本没有用,因为可以直接调用实现类的实例方法,何必再兜圈子通过接口呢?

       诚然这种想法不会带来功能上的任何问题,单违背了面向接口编程的初衷,用接口就是为了解除代码之间的耦合。接口定义了一系列方法提供给外部代码调用,不需要关心具体实现,这又回到了码农皆知的大道理上。然而第一种这样的调用方式并没有解除代码的耦合度,毕竟你使用的仍然是接口的实现类创建类的实例的,除非你直接使用实例化接口(第二种方式),可这样就出现编译错误,因为接口不能实例化。这样一来接口并没有真正意义上实现代码的解耦。

        如果外部调用接口的地方很多,就需要多处实例化实现接口类的实例,如果实现接口类的名称发生变化,那岂不是要改很多处,这不是耦合度很高吗?

      为了解决这样的耦合问题,很多编程IDE引入了容器管理,这样不需要编程人员去手动实例化接口类,有容器代理,从而真正实现代码见间的解除耦合。

你可能感兴趣的:(java,开发语言)