A和B有区别吗?
A 类有私有构造函数:
class A
{
private A()
{ }
}
B 类是密封的并且有一个私有构造函数:
sealed class B
{
private B()
{ }
}
A和B有区别吗?
A 类有私有构造函数:
class A
{
private A()
{ }
}
B 类是密封的并且有一个私有构造函数:
sealed class B
{
private B()
{ }
}
YesA
可以被嵌套类继承,而B
根本不能被继承。这是完全合法的:
public class A {
private A() { }
public class Derived : A { }
}
请注意,任何代码都可以创建new A.Derived()
或继承自A.Derived
(其构造函数是公共的),但源文本之外的任何其他类都A
不能直接继承自A
.
此类的典型用途是具有类枚举值但可以具有自定义行为的类:
public abstract class A {
private A() { }
public abstract void DoSomething();
private class OneImpl : A {
public override void DoSomething() { Console.WriteLine("One"); }
}
private class TwoImpl : A {
public override void DoSomething() { Console.WriteLine("Two"); }
}
public static readonly A One = new OneImpl();
public static readonly A Two = new TwoImpl();
}
根据第二篇文章,如果这是唯一的构造函数,您将无法创建 A 类或 B 类的实例。因为 A 类有一个私有构造函数,由于其保护级别,您不能从它派生,也不能从它派生B带密封。
派生类对基类成员的访问 派生类可以访问基类的公共、受保护、内部和受保护的内部成员。即使派生类继承了基类的私有成员,它也不能访问这些成员。但是,所有这些私有成员仍然存在于派生类中,并且可以完成与基类本身相同的工作。例如,假设受保护的基类方法访问私有字段。该字段必须存在于派生类中,才能使继承的基类方法正常工作。
私有构造函数是一种特殊的实例构造函数。它通常用于仅包含静态成员的类中。如果一个类有一个或多个私有构造函数而没有公共构造函数,则其他类(嵌套类除外)不允许创建该类的实例。
您可以得到一个微小的差异,与代码分析有关。
考虑这段代码:
public class Base
{
public virtual void Function()
{
}
}
public class Derived: Base
{
public static Derived Create()
{
return new Derived();
}
private Derived()
{
// Code analysis warning: CS2214 "Do not call overridable methods in constructors".
Function();
}
}
Derived 构造函数有一个代码分析警告,因为我们正在从它访问一个虚拟方法,这是一个坏事。
但是,如果您进行Derived
密封,代码分析警告就会消失。
所以对你来说有一个微小的和人为的差异。;)
可以实例化一个sealed
类,但不能实例化具有私有构造函数的类。它们都不允许继承,但这不是私有构造函数的目标。
使用私有构造函数的原因是停止实例化。这通常用在静态工厂方法中,您必须调用MyClass::Create(...)
它来创建实例。
这与阻止继承的密封无关。如果您使用私有构造函数来停止继承,那么您使用的是错误的方法。有一些方法可以绕过私有构造函数进行继承。
public class Test
{
private Test()
{
Debug.WriteLine("private constructor has been called in class Test");
}
public virtual string Run()
{
return "Test.Run";
}
public static Test GetTestRequest()
{
return new Test();
}
public static DerivedTest GetDerivedTestRequest()
{
return new DerivedTest();
}
public class DerivedTest:Test
{
public DerivedTest()
{
Debug.WriteLine("public constructor has been called in derived class DerivedTest.");
}
public override string Run()
{
return "DerivedTest.Run";
}
}
}
Debug.WriteLine(Test.GetTestRequest().Run()); Debug.WriteLine(Test.GetDerivedTestRequest().Run());
==================================================== ========== 输出:
在类 Test Test.Run 中调用了私有构造函数
在类测试中调用了私有构造函数 在派生类 DerivedTest 中调用了公共构造函数。派生测试运行
因此,嵌套类可以从具有唯一私有构造函数的外部基类派生。
如果一个类是密封的,就不能定义一个派生自它的类。具有私有构造函数的类可以由类内的工厂方法实例化,也不能由嵌套类继承(取决于它们的访问级别和构造函数,可以由外部代码继承)。此外,任意外部代码可以声明派生自它并满足new()
约束的类。如果派生类不能调用基类构造函数,它自己的构造函数将别无选择,只能抛出异常、崩溃或挂起,但在尝试实际构造实例之前,无法检测到此类行为;代码编译得很好。