Class 在接口和抽象类之间选择时需要考虑的因素是什么?

Class 在接口和抽象类之间选择时需要考虑的因素是什么?,class,interface,abstract,Class,Interface,Abstract,在设计我的软件时,我从界面开始,因为这似乎是“标准”。然后我转向抽象类,因为它们似乎更适合手头的问题。然而,我不确定在做出这个设计选择时是否遗漏了一些考虑因素。除了特定领域的问题,我在选择接口和抽象类之间需要考虑的更一般的因素是什么?继承定义了构图的相似性。接口定义了行为的相似性。从这里,你必须决定合成是否足够重要以覆盖行为。继承定义合成的相似性。接口定义了行为的相似性。从这里,您必须决定组合是否足够重要以覆盖行为。如果您的接口至少在某些功能上也具有合理的默认行为,那么您可能希望使用抽象类来避免

在设计我的软件时,我从界面开始,因为这似乎是“标准”。然后我转向抽象类,因为它们似乎更适合手头的问题。然而,我不确定在做出这个设计选择时是否遗漏了一些考虑因素。除了特定领域的问题,我在选择接口和抽象类之间需要考虑的更一般的因素是什么?

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

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

如果您的接口至少在某些功能上也具有合理的默认行为,那么您可能希望使用抽象类来避免在所有具体实现中使用公共样板代码。否则,请使用接口。

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

当您有多个实例具体化模板方法模式时,请使用抽象类

假设您有三个解析器。一个按“,”清除文件数据,另一个按“”清除,另一个按“|”

然后,您可以拥有一个Commapaser、一个SpaceParser和一个PipeParser,它们都是抽象解析器的子类,并覆盖抽象方法,
getDelimiter()


当类不共享实现,而只是响应相同的方法调用时,请使用接口。

当您有多个具体化模板方法模式的实例时,请使用抽象类

假设您有三个解析器。一个按“,”清除文件数据,另一个按“”清除,另一个按“|”

然后,您可以拥有一个Commapaser、一个SpaceParser和一个PipeParser,它们都是抽象解析器的子类,并覆盖抽象方法,
getDelimiter()


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

我发现大多数时候最好的选择是同时执行这两种操作。当您依赖于基类中发生的事情时,这并不总是可能的同时提供抽象基类和接口允许抽象的实现者有最大的自由度,同样,只要不需要接口的实现者发生什么事情。如果您要求发生某件事,那么您根本不想提供接口,而且您还需要确保您的基类确保始终发生所需的操作

两者都不好:更粘

伪代码示例:

interface IVehicle
{
    void PutCarInGear(Int speed);
}

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

请注意,在本例中,有人可以创建自己的类来实现
IVehile
,然后将其传递给使用
IVehile
的任何对象。该对象不需要是
Vehicle
抽象类的子对象。因此,如果您希望在
PutCarInGear()
方法中发生特定的事情,那么很可能这个新类无法实现该期望。然而,只要
iVihicle
的实现做什么并不重要,那么同时拥有抽象基类和接口是最灵活的抽象。

我发现大多数时候最好的选择是两者兼备。当您依赖于基类中发生的事情时,这并不总是可能的同时提供抽象基类和接口允许抽象的实现者有最大的自由度,同样,只要不需要接口的实现者发生什么事情。如果您要求发生某件事,那么您根本不想提供接口,而且您还需要确保您的基类确保始终发生所需的操作

两者都不好:更粘

伪代码示例:

interface IVehicle
{
    void PutCarInGear(Int speed);
}

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

请注意,在本例中,有人可以创建自己的类来实现
IVehile
,然后将其传递给使用
IVehile
的任何对象。该对象不需要是
Vehicle
抽象类的子对象。因此,如果您希望在
PutCarInGear()
方法中发生特定的事情,那么很可能这个新类无法实现该期望。然而,只要
iVihicle
的实现做什么并不重要,那么拥有抽象基类和接口是最灵活的抽象。

如果它是一个“是”关系,并且应该完成所有功能的子集,则将其作为一个抽象类。如果它是一个“应该做”的关系,则将其保留为接口。

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

多次复制:和其他多次复制:和其他