抽象方法,可能为空

时间:2019-05-20 11:31:06

标签: c# abstract-class

我有一个抽象类,其中包含一个抽象方法,有时仅需要该方法。简而言之,其原因是该类执行了一些代码,有时仅产生输出(然后需要处理)。因此,确实获得输出的抽象类的实现需要实现此方法,而没有输出的实现实际上可以不这样做。抽象类如下所示:

abstract class AbstractWorker
{
    public virtual Execute()
    {
        OutputModel output = await PerformActions();
        await HandleOutput(output);
    }        

    protected abstract Task<OutputModel> PerformActions();
    protected abstract Task HandleOutput(OutputModel);
}

我无法实现方法PerformActions()HandleOutput(),因为它们对于AbstractWorker的特定实现而言非常独立。而且,正如我所说,并非总是要处理输出,但是如果有输出,我就必须强制执行该方法。因此,实现木看起来像这样:

public class ConcreteWorker : AbstractWorker
{
    protected override async Task<OutputModel> PerformActions() 
    {
        // ...do stuff here, which produces no output
        return null;
    }

    protected override async Task HandleOutput(OutputModel output) 
    {
        // Do nothing, since there is no output
        return;
    }
}

虽然上述方法确实有效,但似乎有些愚蠢。但是对于生成输出的情况是必需的。有某种更聪明的方法吗?

3 个答案:

答案 0 :(得分:4)

您不应实现未使用的方法。 SOLID原则,界面隔离:

https://en.wikipedia.org/wiki/Interface_segregation_principle

我将在使用方法的类和不使用方法的类之间放置另一个抽象层。

答案 1 :(得分:2)

您可以在基类中使用默认逻辑将它们虚拟化。

Private Sub CommandButton2_Click()

    Dim n As Long 'it will give you a number
    Dim LastRow As Long
    Dim C As Range

    Application.ScreenUpdating = False

    With ThisWorkbook.Sheets("SheetName") 'change this to the actual sheet name
        LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row 'last row on column A
        For Each C In .Range("A1:A" & LastRow)
            C.Offset(0, 2) = DateDiff("d", C, C.Offset(0, 1))
        Next C
    End With

    Application.ScreenUpdating = True

End Sub

答案 2 :(得分:0)

解决此问题的面向对象的方法是添加另一个抽象层。

AbstractWorker类实现仅具有IAbstractWorker方法的接口(Execute())。 (好吧,由于它是一个异步方法,让我们返回一个Task并将其命名为ExecuteAsync以遵循最佳实践)

让不需要处理输出的工作人员直接实现该接口,
需要处理输出的工作人员使用当前的抽象类。

基本上是这样的:

interface IAbstractWorker
{
    Task ExecuteAsync();
}

abstract class AbstractSepcializedWorker : IAbstractWorker
{
    public async Task ExecuteAsync()
    {
        OutputModel output = await PerformActions();
        await HandleOutput(output);
    }        

    protected abstract Task<OutputModel> PerformActionsAsync();
    protected abstract Task HandleOutputAsync(OutputModel);
}


class Worker : IAbstractWorker
{
    public async Task ExecuteAsync()
    {
        // implementation
    }
}

class SepcializedWorker : AbstractSepcializedWorker
{

    protected override Task<OutputModel> PerformActionsAsync()
    {
        // implementation
    }
    protected override Task HandleOutputAsync(OutputModel)
    {
        // implementation
    }
}

然后,您所有的工作程序类都实现了IAbstractWorker接口,并且可以轻松创建新的具体工作程序类,这些类可以直接实现接口或继承抽象类(并因此通过继承实现)。