Hac*_*ese 29
static表示该类只能有静态成员,您无法创建它的实例.这用于无状态功能(例如,仅定义扩展方法或实用程序方法的类型).您还可以static在非静态类上声明成员.这允许您将功能附加到类型而无需实例化它.
abstract定义所有派生类型共享的基本结构和功能,但不能单独使用.我认为,将它们视为蓝图和合同.这是OOP的核心概念.
Tom*_*cek 22
这是一个简短的总结:
static成员(它只是逻辑上不属于任何标准类实例的方法的容器)关键区别在于您可以从abstract类继承,但不能从static类继承.从技术上讲,.NET运行时没有任何概念static类,因此C#编译器符合他们作为类,它们都abstract和sealed(这意味着你不能从他们那里继承).
因此,static类也是abstract类sealed(虽然如果你是C#程序员,这不是查看问题的常用方法)并且只包含static成员(由C#编译器强制执行).
抽象类旨在用作类继承层次结构的基础.静态类不能是类继承层次结构的基础.
静态类用于单例状态或无状态功能.抽象类不适用于单例功能,因为即使它可能包含静态方法和字段作为静态类,它也不能禁止继承,因此单例使用可能会被子类击败.或者,至少,它会让其他程序员感到困惑,因为它的定义会传达与其实际预期用途不同的意图.
抽象类和静态类之间的表面相似性仅在于两者都不能被实例化.除此之外,它们是完全不同的动物,具有完全不同的用例.
抽象类通过派生类间接实例化。它们提供通用行为和实例状态,但表明需要更多并且必须由派生的具体类提供。例如,Transform可能是一个抽象类:它声明了一个通用Apply(Shape)方法,但没有实现该方法。具体派生类喜欢Rotation或Translation将实现该方法,并且这些类可以被实例化。
静态类无法实例化,任何状态都在类级别而不是实例级别。它们通常用于定义没有与方法相关联的状态的实用方法。 Transform不能是静态类,因为具体的派生类需要每个实例的状态(例如,Rotation需要一个每个实例Angle,因为不同的Rotation变换可能来自不同的角度)。
CLR没有静态类的概念,它特定于C#.编译器通过为类使用CLR属性来实现它:它声明它是抽象的和密封的.这可以防止任何语言实例化这样的类.这就是你运行Ildasm时的样子:
.class public abstract auto ansi sealed beforefieldinit ConsoleApplication1.Test
extends [mscorlib]System.Object
{
}
Run Code Online (Sandbox Code Playgroud)
使其密封是静态类的重点,它被用作静态方法和字段的容器.这使得它们像C或Pascal这样的语言就像全局变量和函数一样.
抽象类恰恰相反,它的设计源于.具有其所有成员抽象的抽象类就像一个接口.C#有一个关键字,使静态类和接口完全相反.