C# 在我的场景C中,抽象和受保护有什么区别#

C# 在我的场景C中,抽象和受保护有什么区别#,c#,.net,C#,.net,具有公共构造函数的公共抽象类与具有受保护构造函数的公共类之间的区别是什么。我们的抽象类中没有任何抽象的函数,但我们希望程序员只能够创建扩展该类的对象 这两个场景都可以编译和工作,但是我不知道在什么场景中使用哪个更好。我从小就明白,虽然不能直接实例化抽象类(只能通过非抽象子类),但抽象类通常应该包含需要由该类的子类实现的抽象函数 在一个公共类中有一个受保护的构造函数不意味着这个类的实例化是不可能的(这是我们唯一的构造函数)。我会用一个受保护的构造函数创建一个公共抽象类 使用abstract可以清楚

具有公共构造函数的公共抽象类与具有受保护构造函数的公共类之间的区别是什么。我们的抽象类中没有任何抽象的函数,但我们希望程序员只能够创建扩展该类的对象

这两个场景都可以编译和工作,但是我不知道在什么场景中使用哪个更好。我从小就明白,虽然不能直接实例化抽象类(只能通过非抽象子类),但抽象类通常应该包含需要由该类的子类实现的抽象函数


在一个公共类中有一个受保护的构造函数不意味着这个类的实例化是不可能的(这是我们唯一的构造函数)。

我会用一个受保护的构造函数创建一个公共抽象类

使用
abstract
可以清楚地表明它实际上是一个抽象类。只有一个
受保护的
构造函数就不那么清晰了

除了子类之外,没有任何东西可以调用
抽象的
构造函数;对于类使用
abstract
关键字,将其保留为public是没有意义的:在类声明中使用abstract修饰符来指示一个类只打算作为其他类的基类。也就是说,抽象类不需要包含任何抽象成员。
abstract
修饰符只是一种明确的方式,表示不应该实例化类,而不是使用技术障碍,例如使构造函数公开不可见

请注意,您描述的技术障碍甚至有一个警告:它仍然可以被称为:

  • 它可以从派生类调用
  • 可以使用反射来调用它
这两种方法都意味着其他使用您的类的开发人员可以做一些您不想做的事情,即实例化您的类,而这两种方法都不可能在抽象类时实现

因此,答案是您应该将类标记为
abstract

请注意,尽管如此,还是建议您保护抽象类的构造函数(以强调该类不能实例化)。如果抽象类具有公共构造函数,诸如FxCop之类的工具将输出警告

这符合使每个成员尽可能清晰可见的一般规则。在抽象类中,构造函数永远不会从公共范围调用,因此不需要可见性。它们只会被派生类的构造函数调用,因此
protected
是抽象类中任何构造函数的合理可见性


因此,还可以使抽象类的任何构造函数(最多)
受保护

声明类中的静态方法仍然可以调用私有或受保护的构造函数。抽象类必须具有要实例化的派生类。例如,singleton模式使用通过公共静态方法/属性调用的私有构造函数。

带有受保护或内部构造函数的公共抽象类表示您希望调用代码如何使用它。使用不可访问的构造函数实际上可能会令人困惑。

我认为抽象类更清楚地表达了您的设计意图。理解这些差异是很好的,但是理解“您需要解决什么问题?”更重要,这取决于您的答案,实例的创建可以通过不同的方式完成(例如工厂类),这些方式可以独立于声明的类类型。有一个事件强制执行这一点。很抱歉,但我真的不明白为什么-类被声明为抽象类的事实不足以说明这一点吗?我的意思是,阅读“抽象”一词,告诉读者这个类是抽象的——它怎么能变得更清楚呢?@Daniel:这个想法可能是为了给所有成员提供他们所需的最低可见性。构造函数在抽象类中不公开使用;它只会在派生类中使用(更准确地说,在继承的构造函数调用中),这就是为什么它应该被保护的原因。在构造函数中添加“protected”基本上是一种简单的方法。但是,它确实告诉类的审阅者,您理解抽象的真正含义:)。除了子类之外,没有任何东西可以调用抽象构造函数;再举一个例子:如果代码没有为类提供任何实例构造函数,那么编译器会为您编写一个构造函数,即默认构造函数。仅当类是非抽象类时,此构造函数才是公共的。对于抽象类,此“不可见”构造函数将受到保护。见本标准第10.11.4段。这是在抽象类中不使用公共构造函数的又一个例子,我喜欢这个答案。对于非抽象类
Base
,即使所有(实例)构造函数都受
保护
,也可以在
Base
本身或从
Base
派生的某个类中引入代码,即:
var b=new Base(…)