2

我刚开始使用抽象类,想知道我是否以正确的方式使用它们。在我的示例中,我有一个 Windows 窗体应用程序,其中 Form1 是应用程序的主 UI。在 Form1 中,我有一个将调试消息写入富文本框的方法。我目前有一堆不同的类,它们都有相同的方法将消息写回主 UI 富文本框。但是,我想知道将这个功能作为抽象类的一部分是否有意义,只是让我的所有其他类继承这个功能,如下所示?

using System;
using System.Windows.Forms;

namespace abstractTest
{
    /// <summary>
    /// Main User Interface
    /// </summary>
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public void RTBWriteLine(string message)
        {
            /* Print (append) message to the debug richtextbox */
            this.richTextBox1.AppendText(message + Environment.NewLine);

            /* Select the last entered message */
            this.richTextBox1.Select(richTextBox1.Text.Length, 0);

            /* Scroll to selected message */
            this.richTextBox1.ScrollToCaret();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Class1 c1 = new Class1(this);
            Class2 c2 = new Class2(this);
        }
    }

    public abstract class absTest
    {
        protected Form1 MainUI;

        public virtual void MainRTBWriteLine(string msg)
        {
            if (MainUI != null)
            {
                MainUI.RTBWriteLine(msg);
            }
        }
    }

    public class Class1 : absTest
    {
        public Class1(Form callingForm)
        {
            MainUI = callingForm as Form1;
            MainRTBWriteLine("This is Class1");
        }
    }

    public class Class2 : absTest
    {
        public Class2(Form callingForm)
        {
            MainUI = callingForm as Form1;
            MainRTBWriteLine("This is Class2");
        }
    }
}

编辑:我的主要目标是使 DTBWriteLine(在以某种方式更新主 UI 的许多其他方法中)可用于我的所有类,但只有一个位置的代码。现在,我在我创建的每个类中都复制了以下方法(以及许多其他方法):

public virtual void MainRTBWriteLine(string msg)
{
    if (MainUI != null)
    {
        MainUI.RTBWriteLine(msg);
    }
}

如果把它放在一个抽象类中不是最好的方法,那是什么?

4

6 回答 6

3

是的,这个场景是使用抽象类的完美示例。

当您在继承树中共享功能时。

于 2013-01-13T20:28:41.393 回答
1

对我来说,您所追求的似乎是一个单独的 DebugLogger 类,它唯一关心的是将调试消息记录到文本框。

然后你的其他类只会将调试日志委托给这个类,而不是继承与它们的主要功能没有太大关系的这个附加功能。

于 2013-01-13T20:52:18.500 回答
1

在这种情况下,抽象类是一种选择,是的。另一种选择(特别是如果您想从其他地方重用相同的功能)是在单独的类中创建一个实用程序方法。继承是实现代码重用的一种方式,但它并不总是最好的选择——仔细考虑这些选项。

于 2013-01-13T20:30:48.260 回答
0

这是有道理的,并用抽象类反映了这个想法。在您的示例中,它还为您提供了一个很好的关注点分离,您的 absTest 实现使您能够在需要时在单个点交换日志记录策略。

于 2013-01-13T20:33:04.877 回答
0

抽象类被广泛用于实现模板方法模式。检查C# 实现示例

我要补充一点,在您的示例中不必完全使用abstract关键字。absTest可能并非没有任何危害,并且在构造函数实现abstract的情况下它将完全正常工作。absTest(Form callingForm)

于 2013-01-13T20:36:11.893 回答
0

根据文档,抽象类的要点:

在类声明中使用 abstract 修饰符来指示一个类仅作为其他类的基类

  • 抽象类不能被实例化。
  • 抽象类可能包含抽象方法和访问器。
  • 不能用sealed修饰符修改抽象类,这意味着该类不能被继承。
  • 从抽象类派生的非抽象类必须包括所有继承的抽象方法和访问器的实际实现。
于 2013-01-13T20:28:26.370 回答