Oop 面向对象-放置此接口声明的位置

Oop 面向对象-放置此接口声明的位置,oop,interface,abstract-class,Oop,Interface,Abstract Class,我有几个问题要问聪明的人,涉及到面向对象设计和接口以及抽象基类。考虑下面的场景: 我有一个抽象的bass类“DataObjectBase”和一个派生类“UserDataObject”。我还有一个接口“IDataObject”。该接口当然公开了我的数据对象必须公开的所有公共方法和属性,您可能会猜到抽象库实现了所有数据对象通用的方法和属性 我的问题是,如果抽象bass类DataObjectBase实现了接口IDataObject中指定的所有内容,那么该接口应该在基类上声明,还是在派生类上声明 在C#

我有几个问题要问聪明的人,涉及到面向对象设计和接口以及抽象基类。考虑下面的场景:

我有一个抽象的bass类“DataObjectBase”和一个派生类“UserDataObject”。我还有一个接口“IDataObject”。该接口当然公开了我的数据对象必须公开的所有公共方法和属性,您可能会猜到抽象库实现了所有数据对象通用的方法和属性

我的问题是,如果抽象bass类DataObjectBase实现了接口IDataObject中指定的所有内容,那么该接口应该在基类上声明,还是在派生类上声明

在C#中,基类上声明的接口被隐式应用于派生类,但这是最佳实践吗?在我看来,在基类上实现接口使派生类实现接口变得不那么明显,但随后又要求为每个派生类指定接口

另外,如果基类不是抽象的,reccomendation会改变吗

第二个子问题:如果基类实现IDataObject接口的所有方法/属性,那么该接口是否需要?基类typename可以简单地用来代替接口名,即:

私有DataObjectBase_dataObject
私有IDataObject_数据对象

在上面的示例中(在这个示例中,基类实现了接口公开的所有内容),可以为两者分配相同的派生类型。就我个人而言,我总是在这些情况下使用界面,但我感兴趣的是倾听人们的想法


提前感谢。

如果您的用户类总是从一个基类继承,那么您就不需要该接口。如果可能有与接口匹配但不是从基类派生的类,则使用接口


至于隐藏在基类中的接口,因此在用户类中不立即可见,这是正常的,可以由编译器处理。这也是好的命名约定的用武之地——您的UserDataObject和DataObjectBase的名称都与IDataObject匹配。您可以向类文件添加注释,该注释表示它继承自IDataObject,但它可以从DATAObjutBasic继承,而它看起来像是从它的名称继承了IDATAObjor。

< P>我思考这些问题的方式是考虑不同的人阅读代码,如果您喜欢的话,请使用“角色”。还考虑系统的总体可维护性。 首先,有一些代码希望使用该接口。它是根据接口编写的,作者(应该)对实现没有兴趣。这就是我们提供接口类的原因。从这个角度来看,抽象基类只是许多可能的实现层次结构之一。不要将实施细节告诉此角色。保留接口

然后是设计实现的角色。他们提出了一种可能的方法并发现了一些变体,因此他们希望将通用代码整合在一起。抽象基类-在这里填写常见的内容,让详细的实现人员填补空白。通过提供抽象方法来帮助他们说“你的代码在这里”。请注意,这些方法不仅需要是接口中的方法。还要注意,这个抽象基类甚至可能实现多个接口!(它是一个聪明的工人,但同时也是一个中等职业者。)

然后我们就有了一个角色,这个角色实际上完成了精细的详细实现。填补这里的空白。很容易理解。在这种情况下,你甚至不需要考虑这样的接口。你的工作是使抽象类具体化


底线是。。。我使用接口和基类。您将接口放在基类上。我们不会通过将其添加到实现类中来增加价值。

需要提到的另一件事是,使用接口可以更容易地实现自动化测试

例如,假设接口的其中一个方法应该抛出异常(例如“DatabaseConnectionOstException”),您希望测试客户机代码,以检查它在这种情况下的行为是否正确

提供抛出异常的接口的实现是一件简单的事情,允许编写测试

如果您使用抽象基类而不是接口,那么这个操作会有点棘手(好的,您可以使用mock,但是接口解决方案要干净得多)