抽象基类中的方法如何从派生类调用构造函数
本文关键字:派生 调用 构造函数 基类 方法 抽象 | 更新日期: 2023-09-27 18:17:22
作为一个例子,考虑。net SHA256Managed类
SHA256 managed继承自抽象类SHA256, SHA256有一个名为Create()的方法。文档中说Create()实例化了SHA256默认实现的一个实例。
我可能会写像
这样的东西using (SHA256Managed Sha256Managed = new SHA256Managed())
{
// code
}
而微软的例子选择使用:
SHA256 mySHA256 = SHA256Managed.Create();
像Create()这样的方法(来自基类)如何实例化派生自它的类的实例?
函数可以返回任何你想要它返回的实例;)
在这种情况下,256Managed
的实例仍然可以被转换为SHA256
这样的事情是完全可行的:
public class SHA256Managed
{
public static SHA256 Create()
{
return new SHA256Managed();
}
}
在SHA256
类中,Create
方法是一个静态方法,它返回System.Security.Cryptography默认实现的实例。SHA256'(根据方法文档)。这个默认实现是SHA256Managed
——SHA256
的一个非抽象子类。
SHA256
和SHA256Managed
类是在同一个程序集中定义的,所以SHA256Managed
对SHA256.Create
来说是一个有效的类。
下面是一个带有静态Create
方法的抽象基类示例,该方法创建了一个非抽象派生类的实例:
public abstract class A
{
public static A Create()
{
return new B();
}
public abstract void DoSomething();
}
public class B : A
{
public override void DoSomething()
{
// do nothing.
}
}
实际上发生的事情是编译器在编译这些成员的代码之前为整个程序集构建一个类及其成员的列表。因此,在编译A.Create
方法时,编译器已经知道B
类的存在和结构。
这也是为什么在类中把属性和方法放在之后的第一个你引用它们的点,像这样:
class C
{
void some_method()
{
++counter;
}
int counter;
}
编译器在编译some_method
的代码之前已经知道C
类的整个结构,因此它可以编译语句++counter;
而不会出错。
类的方法或属性可以随意使用任何派生类(甚至自己作为字段)。语言中没有限制方法只能使用自己的对象和基类。
对于抽象类,你唯一不能做的就是new
这样一个类的实例,调用这样一个类的静态成员,返回任何非抽象类/结构的任何有效实例是完全可以的。
下面的有效代码表明可以返回您自己的类,甚至派生类:
class Base
{
public Derived Property1 {get;set;}
public Base Property2 {get;set;}
public static Base Create()
{
return new Derived();
}
public static Derived Create2()
{
return new Derived();
}
}
class Derived : Base
{
}
通常,基类不应该有任何派生类的知识-但是它可以实例化任何它想要的。
然而,在SHA256的情况下,它的Create()方法"实例化默认实现",被列为SHA256Managed。因为SHA256Managed没有创建方法,它调用它的基类create()并获得自己的一个实例。这只能发生在基本实现显式实例化SHA256Managed的情况下,就像Alexei + Tom所示:
public static SHA256 Create()
{
return new SHA256Managed();
}
SHA256Managed.Create()
正在调用SHA256
的Create()
方法作为基类。Create()
方法是一个不可重写的静态方法,它是通过new
关键字在SHA256Managed
类上实现的。查看更多信息编辑
因此,在深入挖掘之后(使用ILSPY),我发现SHA256
的Create()
方法并没有那么简单,它被称为另一个类CryptoConfig.CreateFromName
。
SHA256Managed
(派生类)的信息存在于某种配置机制中
@280Z28:谢谢你的更正