依赖注入:基于接口和类的松散耦合机制之间的区别?

时间:2015-08-30 20:59:40

标签: java dependency-injection loose-coupling

假设我有2个配置。

第一个:

interface I {
    ...
}

class A implements I {
    ...
}

class B implements I {
    ...
}

class Component {
    I i;    
    Component (I i) {
        this.i = i;
    }
}

第二个:

class C {
    ...
}

class A extends C {
    ...
}

class B extends C {
    ...
}

class Component {
    C c;    
    Component (C c) {
        this.c = c;
    }
}

这两种配置使用两种不同的松耦合机制(基于接口和基于类)的区别是什么?

为什么我需要在类上使用接口?

3 个答案:

答案 0 :(得分:1)

一个对象可以实现多个接口,但只能扩展一个类,所以有时松耦合库的用户可能无法扩展你的类。

当你扩展时,你将超类的代码合并到你的代码中,有时没有代码可以合并,所以实现更适合。

最后它不是同一个范例,当你写" B扩展A"你说"我是A,我做同样的事情,但我也可以做其他事情"。当你写" B实现A"你说"我是B,但你可以把我当成A"。

长话短说,唯一的实际原因是第一个。

答案 1 :(得分:1)

主要是,使用类是一种更重的方法。基类通常包含具体(非抽象)方法。如果你从它们派生出来,你还需要继承你可能不想要的具体方法。

例如,假设您希望从decorator pattern等组合设计模式中受益。在这里,您的装饰器还需要从基类派生并继承具体方法。但是,你的装饰者不需要具体的方法来运作。

总之,如果您的抽象是基于类的,那么进行对象组合会更加困难/不洁净。

另一方面,通过接口进行抽象,并不强制实现类继承任何具体的方法实现。因此,它更干净。

答案 2 :(得分:0)

基于接口的层次结构是一种很好的设计方法,因为它简化了实现:您始终可以实现接口,但并不总是可以扩展类(例如,最终类)。或者,另一方面,并​​非总是一个类的作者希望它被扩展。

因此, 对使用类的接口非常感兴趣,因为通过这种方式,您可以接受更广泛的实现。例如:

使用课程:

class Component
{
    AbstractList c;
    Component (AbstractList c){...}
}

... Component将接受ArrayList或Vector。

相反,使用接口:

class Component
{
    List c;
    Component (List c){...}
}

... Component将能够接受ArrayList,Vector,CopyOnWriteArrayList ......