C# 我应该将属性声明为接口还是基类(当它们实现两者时)?
我有一个类以类似的方式使用一组属性(为了简洁起见,示例中只显示了两个)。 一般行为在基类上定义,而特定行为在特定接口中定义 问题是:如果我将它们声明为基类,我必须将它们转换为接口来调用接口方法。现在,若我将它们声明为接口,当我想要调用基类方法时,我必须将它们转换为基类 在这里使用接口时,我的目标是提高可测试性(稍后使用依赖项注入),并培养“向接口编程”的习惯,但我无法决定哪种方式是最好的,甚至无法决定整个原理是否是好的C# 我应该将属性声明为接口还是基类(当它们实现两者时)?,c#,inheritance,interface,casting,C#,Inheritance,Interface,Casting,我有一个类以类似的方式使用一组属性(为了简洁起见,示例中只显示了两个)。 一般行为在基类上定义,而特定行为在特定接口中定义 问题是:如果我将它们声明为基类,我必须将它们转换为接口来调用接口方法。现在,若我将它们声明为接口,当我想要调用基类方法时,我必须将它们转换为基类 在这里使用接口时,我的目标是提高可测试性(稍后使用依赖项注入),并培养“向接口编程”的习惯,但我无法决定哪种方式是最好的,甚至无法决定整个原理是否是好的 public class Conductor { // These
public class Conductor
{
// These properties inherit from base class
// and implement one specific interface each:
// declared as interface:
IPlotterHelper _plotter_helper = new PlotterHelper();
// declared as base class:
Helper _file_writer_helper = new FileWriterHelper();
// When using handlers defined in specific interfaces:
// have to cast this:
this.NewFrame += ((IPlotterHelper)_file_writer_helper).ProcessFrame();
// but not this:
this.NewSamples += _plotter_helper.ProcessSamples();
// While when using handlers from the base class
// have to cast this to the base class (since it is an interface):
this.CommandSent += ((Helper)_plotter_helper).RunCommand;
// but not this:
this.CommandSent += _file_writer_helper.RunCommand;
}
internal class FileWriterHelper : Helper, IFileWriterHelper
{
IFileWriterHelper.ProcessFrame()
{
// ...
}
// ...
}
internal class PlotterHelper : Helper, IPlotterHelper
{
IPlotterHelper.ProcessSamples ()
{
///
}
// ...
}
internal class Helper
{
internal void RunCommand()
{
// ...
}
}
很难准确地看到您正在尝试做什么,但似乎这可能是一个更合适的设计:
public class Conductor
{
private IPlotterHelper _plotter_helper = new PlotterHelper();
private IFileWriterHelper _file_writer_helper = new FileWriterHelper();
public void Conduct()
{
_file_writer_helper.ProcessFrame();
_file_writer_helper.RunCommand();
_plotter_helper.ProcessSamples();
_plotter_helper.RunCommand();
}
}
internal interface IHelper
{
void RunCommand();
}
internal interface IFileWriterHelper : IHelper
{
void ProcessFrame();
}
internal interface IPlotterHelper : IHelper
{
void ProcessSamples();
}
internal class FileWriterHelper : Helper, IFileWriterHelper
{
public void ProcessFrame()
{
}
}
internal class PlotterHelper : Helper, IPlotterHelper
{
public void ProcessSamples()
{
}
}
internal class Helper : IHelper
{
public void RunCommand()
{
}
}
当我面临接口中默认行为的愿望时,我通常会考虑使用一个抽象基类,要么使用受保护的助手方法,要么使用一组抽象接口方法或“接口”方法的默认实现。即使我只从一个具体的实现开始,情况也可能如此
许多人将抽象类和接口视为同一大类的实现选项 抽象类的问题是单一继承,因此,如果抽象类真的要作为类层次结构的基础(即使是浅层次结构),我们应该只使用抽象类。接口可以用来装饰具有共同行为的类(来自不同层次结构) 对于测试,我看不出使用接口伪造与使用抽象类伪造之间有多大区别,但这可能取决于您的测试基础架构在这种情况下,我将使用一个抽象类,而忽略接口(除非它已经存在,在这种情况下,您没有任何选择)。接口和抽象类的目的相同:提供抽象。确保抽象一致,如果基类有公共成员,确保它们也在接口上
但是,为什么我需要抽象类或接口呢正确的。不管是基类还是接口,你都不需要。我会删除基类。仅供参考,在命名变量时,我不会使用下划线,除非在开头(表示它们是字段)
\u plotter\u helper
是错误的,应该是\u plotter helper
等等。你所说的“特定行为在特定接口中定义”是什么意思,因为接口不定义行为?如果你发布的代码能够真正编译,那也太棒了。“现在是狗的早餐。”我表达得很糟糕。我想说的是“多态性”,即每个接口实现者将以不同的方式实现给定的方法。谢谢你的回答!我想我在解释时没有说清楚,但事实是:RunCommand
在Helper
中定义了一个通用的实现(现在我想这是一个非常糟糕的名字)。之所以这样命名,是因为指挥给它发出命令,以便它“帮助”执行协调一致的动作(与其他助手一起)。但是每个专门的助手也有专门的成员来做额外的事情(如ProcessSamples
,ProcessFrames
,这些东西与命令运行功能分离。哇,那太好了!即使现在我正在解决这个问题,我相信这完全正确地回答了问题。谢谢!好吧,这就是我最后要做的。我不是IPlotterHelper
,而是我有一个直接的PlotterHelper
子类,所以我不必再回到Helper
了。谢谢!