了解接口和基类的使用

时间:2012-04-19 18:11:39

标签: asp.net vb.net interface base-class

我知道接口和基类上有很多帖子,但是我很难理解正确的设计模式。

如果我要编写一个报告类,我的初始版本是创建一个包含所有报告将实现的核心属性,方法等的接口。

例如:

Public Interface IReportSales

Property Sales() As List(Of Sales)
Property ItemTotalSales() As Decimal

End Interface

Public Interface IReportProducts

Property Productss() As List(Of Inventory)
Property ProductsTotal() As Decimal

End Interface

然后我假设我有一个类来实现接口:

Public Class MyReport
Implements IReportSales


Public Property Sales() As System.Collections.Generic.List(Of Decimal) Implements IReportItem.Sales
    Get
        Return Sales
    End Get
    Set(ByVal value As System.Collections.Generic.List(Of Decimal))
        Items = value
    End Set
End Property

Public Function ItemTotalSales() As Decimal Implements IReport.ItemTotalSales
    Dim total As Decimal = 0.0
    For Each item In Me.Sales
        total = total + item
    Next
End Function

End Class

我的想法是它应该是一个界面,因为其他报告可能不会使用" Items",这样我就可以实现用于给定报告类的对象。

我离开了吗?我还应该刚创建一个基类吗?我没有创建基类的逻辑是,并非所有报告类都可以使用" Items"所以我不想在不使用它们的地方定义它们。

2 个答案:

答案 0 :(得分:2)

为了尝试回答您的问题,抽象类用于为相关类提供共同的祖先。 .Net API中的一个示例是TextWriter。这个类为所有各种类提供了一个共同的祖先,其目的是以某种方式编写文本。

接口更适合用作不同对象的适配器,这些对象不属于对象的“系列”,但具有相似的功能。使用.Net API中的各种集合可以看到一个很好的例子。

例如,ListDictionary类提供了管理对象集合的能力。他们不通过继承共享共同的祖先,这是没有意义的。为了便于它们之间的互操作,它们实现了一些相同的接口。

两个类都实现IEnumerable。这样可以干净地允许您使用ListDictionary类型的对象作为需要IEnumerable的任何操作数。太棒了!

现在,在您设计新软件的情况下,您想要考虑它如何适合您的问题空间。如果通过继承抽象类为这些类提供共同的祖先,则必须确保从其继承的所有项都是真正的基类型。 (例如,StreamWriterTextWriter。不恰当地使用类继承可能会使您的API在将来很难构建和修改。

假设您为您的报告创建了一个抽象类ReportBase。它可能包含一些非常通用的方法,所有报告都必须具有这些方法。也许它只是指定方法Run()

然后,您只需要生成一种类型的报告,以便定义从Report继承的具体ReportBase类。一切都很棒。然后,您会发现需要添加更多类型的报告,例如XReportYReportZReport。它们的含义并不重要,但它们的工作方式不同,并且有不同的要求。所有报告都会生成漂亮的HTML输出,每个人都很高兴。

下周,您的客户说他们希望XReportYReport能够输出PDF文档。现在有很多方法可以解决这个问题,但显然在您的抽象类中添加OutputPdf方法是一个糟糕的想法,因为其中一些报告不应该或不能支持这种行为!

现在这是接口可能对您有用的地方。假设您定义了几个接口IHtmlReportIPdfReport。现在,应该支持这些不同输出类型的报告类可以实现这些接口。然后,这将允许您创建一个函数,例如CreatePdfReports(IEnumerable<IPdfReport> reports),它可以获取实现IPdfReport的所有报告,并执行它们需要做的任何事情,而无需考虑适当的基本类型。

希望这有帮助,因为我不熟悉你想要解决的问题,所以我在这里嘻嘻哈哈。

答案 1 :(得分:0)

是的,如果您不知道有多少报告不会使用项目,您可以去Abastract课程。

另一个好主意是:

您还可以创建Interface和Abstract类

在Interface中定义Sales,创建两个抽象类,一个用于实现两者的Reports,另一个用于Report不实现Sales。实现两者的接口

首先定义两种方法(实施销售),然后仅在第二种方式实施销售。

为两个抽象类指定适当的名称,例如ReportWithItemsBase或ReportWithoutItemsBase。

通过这种方式,您还可以在派生报告类时实现自我解释的命名基类。