在界面和抽象类之间进行选择时需要考虑哪些因素?

时间:2010-01-25 04:10:18

标签: class interface abstract

在设计我的软件时,我开始使用接口,因为这似乎是“标准”。然后我切换到抽象类,因为它们似乎更适合手头的问题。但是,我不确定在做出这个设计选择时是否错过了一些注意事项。除了特定领域的问题,我考虑过在接口和抽象类之间进行选择时需要考虑哪些更常见的因素?

5 个答案:

答案 0 :(得分:2)

继承定义了组合的相似性。接口定义了行为的相似性。从那里你必须决定组成是否足够重要以覆盖行为。

答案 1 :(得分:2)

我发现最好的选择大部分时间都是两者兼而有之。当你依赖基类中发生的事情时,这并不总是可行的。 同样,只要您不需要接口的实现者发生某些事情,提供抽象基类和接口就可以实现抽象实现者的最大自由度。如果您要求发生了某些事情,那么想要提供一个接口 - 您还需要确保您的基类确保了这一点行动总是发生......

两者兼顾:更多粘性。

示例伪代码:

interface IVehicle
{
    void PutCarInGear(Int speed);
}

abstract class Vehicle : IVehicle
{
    public void PutCarInGear(Int speed)
    {
        //base implementation
    }
}

请注意,在此示例中,有人可以创建自己的实现IVehicle的类,然后将其传递给需要IVehicle的任何内容。该对象不需要是Vehicle抽象类的子元素。因此,如果您期望在PutCarInGear()方法中发生某些特定事件,那么新类很可能无法满足该期望。但是,只要IVehicle的实现无关紧要,那么它就是拥有抽象基类和接口的最灵活的抽象。

答案 2 :(得分:0)

如果您的界面对至少某些功能也有合理的默认行为,您可能希望使用抽象类来避免所有具体实现中的常见样板代码。否则,请使用界面。

答案 3 :(得分:0)

如果有多个实例可以使用模板方法模式,则使用抽象类。

假设您有三个解析器。一个用“,”来消除文件的数据,另一个用“”消除,另一个用“|”

然后你可以拥有一个CommaParser,一个SpaceParser和一个PipeParser,它们都是Abstract Parser的子类,并且覆盖了抽象方法,getDelimiter()

当类不共享实现时使用接口,但仅响应相同的方法调用。

答案 4 :(得分:0)

如果它是一个“是一个”关系并且应该做子集/所有功能,请将它保留为抽象类。如果它是“应该做”的关系,请将其保留为界面。