我刚开始使用抽象类,想知道我是否以正确的方式使用它们。在我的示例中,我有一个Windows窗体应用程序,其中Form1是应用程序的主UI。在Form1中,我有一个将调试消息写入richtextbox的方法。我目前有一堆不同的类,它们都有相同的方法将消息写回主UI richtextbox。但是,我想知道将此功能作为抽象类的一部分是否有意义,只是让我的所有其他类继承此功能,如下所示?
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);
}
}
如果把它放在抽象类中不是最好的方法,那是什么?
答案 0 :(得分:3)
是的,这个场景是使用抽象类的完美示例。
在继承树中共享功能时。
答案 1 :(得分:1)
在这种情况下,抽象类是一种选择,是的。另一种方法(特别是如果你想从其他地方重用相同的功能)将在一个单独的类中创建一个实用程序方法。继承是实现代码重用的一种方式,但它并不总是最佳选择 - 仔细考虑选项。
答案 2 :(得分:1)
对我而言,您所看到的是一个单独的DebugLogger类,其唯一的问题是将调试消息记录到文本框中。
然后你的其他类只会将调试日志记录委托给这一个类而不是继承这个与其主要功能无关的附加功能。
答案 3 :(得分:0)
根据文档,抽象类的要点:
在类声明中使用abstract修饰符来表示a class仅用作其他类的基类
- 无法实例化抽象类。
- 抽象类可能包含抽象方法和访问器。
- 无法使用sealed修饰符修改抽象类,这意味着无法继承该类。
- 从抽象类派生的非抽象类必须包括所有继承抽象方法的实际实现 访问器。
答案 4 :(得分:0)
这很有意义,并用抽象类反映了这个想法。在您的示例中,它还为您提供了一个很好的关注点,您的absTest实现可以让您在需要时在单点交换日志记录策略。
答案 5 :(得分:0)
抽象类广泛用于实现Template Method模式。检查C# implementation samples。
我想补充一点,在您的示例中,使用完全abstract
关键字并不是必需的。 absTest
可能不会abstract
没有任何伤害,并且在absTest(Form callingForm)
构造函数实现的情况下它将完全正常运行。