选择继承或接口来实现Java中的设计模式?

时间:2010-06-09 13:59:55

标签: java design-patterns

我只是想在我的Java代码中注入一些设计模式,但我不知道使用哪种样式 - 是继承还是接口首选?为什么?

4 个答案:

答案 0 :(得分:9)

设计模式不是随机注入应用程序的东西。它们是设计时的各种东西,而不是在你的代码已经烘烤后撒在你的代码上的帕玛森奶酪。

尽管如此,Josh Bloch的开创性 Effective Java 强烈鼓励开发人员使用接口来实现共享行为,而不是使用继承。这符合我自己的经验。

ETA:除其他原因外,如果您正在实现一个接口,您可以轻松地创建该接口的模拟以用于测试,而不必担心继承层次结构的其余部分。

答案 1 :(得分:5)

设计模式不会“注入”您的代码 - 您首先需要注意的是,您的问题类似于许多其他人解决的问题,并且他们已经提炼出一种解决问题的模式。最着名的是here

另外,是否要使用继承(也称为扩展)或接口依赖。通常界面和构图效果更好。

答案 2 :(得分:2)

这两个功能并不相互排斥。接口和实现指定类型和与类型的兼容性。继承允许有效地共享代码。在经典设计中,类型层次结构使用接口表示,而代码重用是使用继承实现的。

答案 3 :(得分:1)

我同意不应该考虑使用某些设计模式注入OR。设计模式旨在解决给定环境中的非常具体的问题。

关于接口和继承:

当您需要运行时多态时,正在使用

接口。因此,您定义了一个接口,您可以拥有多个不同的实现。在客户端代码中,您只需将引用声明为接口类型即可。现在,您不必担心在运行时传递给客户端的实际对象类型。您只关心在引用上调用方法。

 interface Car {
        void startEngine();

        void stopEngine();
    }

    class Maruti implements Car {

        public void startEngine() {
            System.out.println("Maruti engine started");
        }

        @Override
        public void stopEngine() {
            System.out.println("Maruti engine stopped");
        }
    }

    class Porsche implements Car {

        @Override
        public void startEngine() {
            System.out.println("Porsche engine started");
        }

        @Override
        public void stopEngine() {
            System.out.println("Porsche engine stopped");
        }
    }

在上面作为客户端的示例中,您只需将引用声明为Car类型。在运行时,你可以拥有Maruti对象或保时捷对象,你不关心。你关心的只是调用startEngine或stopEngine。

继承通常用于代码可重用性和可扩展性。因此,您在两个类中有共同的代码,并且两者似乎都属于一个公共类型,然后您可以创建一个父类(有时候是抽象的)并在父类中移动公共代码。这样你就可以摆脱重复的代码。另一个用例是可扩展性,有时您无法控制类的源代码,仍然希望添加/更改某些行为。您可以使用继承并覆盖某些方法。

还有一个名为“composition”的东西,它是一种优于继承可扩展性的方法。