抽象类和静态类之间有什么区别?

两者都不可实现。 有什么区别,在什么情况下你可能会使用其中一种?

static表示该类只能有静态成员,您无法创建它的实例。 这用于无状态function(例如,仅定义扩展方法或实用程序方法的类型)。 您还可以在非静态类上声明成员static 。 这允许您将function附加到类型而无需实例化它。

这里有关于使用静态成员和类的更多细节 。

abstract s定义了所有派生类型共享的基本结构和function,但不能单独使用。 我认为它们是蓝图和合约。 这是OOP的核心概念。

这里有关于使用摘要的更多细节 。

这是一个简短的总结:

  • 静态类只能包含static成员(它只是逻辑上不属于任何标准类实例的方法的容器)
  • 抽象类可以包含所有常见类型的成员(静态,抽象和实例)

关键区别在于您可以从abstract类inheritance,但不能从static类inheritance。 从技术上讲,.NET运行时没有任何static类的概念,因此C#编译器将它们视为abstractsealed (意味着您不能从它们inheritance)。

因此, static类也是sealed abstract类(尽管如果您是C#程序员,这不是查看问题的常用方法)并且只包含static成员(由C#编译器强制执行)。

抽象类旨在用作类inheritance层次结构的基础。 静态类不能是类inheritance层次结构的基础。

静态类用于单态或无状态function。 抽象类不适用于单例function,因为即使它可能包含静态方法和字段作为静态类,它也不能禁止inheritance,因此单例使用可能会被子类击败。 或者,至少,它会让其他程序员感到困惑,因为它的定义会传达与其实际预期用途不同的意图。

抽象类和静态类之间的表面相似之处仅在于它们都不能被实例化。 除此之外,它们是完全不同的动物,具有完全不同的用例。

CLR没有静态类的概念,它特定于C#。 编译器通过为类使用CLR属性来实现它:它声明它是抽象的密封的。 这可以防止任何语言实例化这样的类。 这就是你运行Ildasm时的样子:

 .class public abstract auto ansi sealed beforefieldinit ConsoleApplication1.Test extends [mscorlib]System.Object { } 

使其密封是静态类的重点,它被用作静态方法和字段的容器。 这使得它们像C或Pascal这样的语言就像全局变量和函数一样。

抽象类恰恰相反,它的设计源于。 具有其所有成员抽象的抽象类就像一个接口。 C#有一个关键字,使静态类和接口完全相反。

抽象类通过派生类间接实例化。 它们提供了常见的行为和实例状态,但表明需要更多,并且必须由派生的具体类提供。 例如, Transform可能是一个抽象类:它声明了一个常见的Apply(Shape)方法,但没有实现该方法。 像RotationTranslation这样的具体派生类将实现该方法,并且可以实例化这些类。

静态类无法实例化,任何状态都在类级别而不是实例级别。 它们通常用于定义实用程序方法,其中没有与方法关联的状态。 Transform不能是静态类,因为具体派生类需要每个实例状态(例如, Rotation需要每个实例Angle ,因为不同的Rotation变换可以是不同的角度)。

抽象类旨在用作基类; 他们不能有直接的实例。 相反,您必须派生子类,它提供了抽象基类中(通常是故意的)遗漏的内容。

示例:考虑您有一个复杂的应用程序,用户可以登录到该应用程序。 应该使用各种身份validation机制,比如LDAP,NTLM,您可以使用它。 在这样的上下文中建模“用户”或“主体”的一种方法是将所有这些机制中的共同点收集到抽象基类中,并在实际实现进入的地方留下“空白”(抽象方法)玩:

 abstract class Authenticator { protected Dictionary userCache; ... public User LoadUser(string name) { User user; if( userCache.TryGet(name, out user) ) return user; else { user = LoadFromStore(name); userCache.Add(name, user); return user; } } protected abstract User LoadFromStore(string name); } 

在这里,用户的缓存是一个常见的问题,在基本情况下建模,而实际的retreival留给子类提供。

静态类是完全不同的事情。 它们本质上是一个保持实用function的地方:

 static class StrUtil { public static string TrimWhitespace(string str) { ... } } 

将它们视为某种特殊的命名空间,它只能包含静态成员。 基本上,放置function的地方。

抽象类的主要目的是定义一个或多个抽象方法。 任何扩展Abstract类的类都将实现抽象方法,否则它也需要声明为“Abstract”。

但是,它也可以将类声明为“Abstract”而不实现其中的任何抽象方法。 请参阅下面的示例。

公共抽象类AbstractTest {

 public void abcd(){} public static void main(String[] args) { System.out.print("hi..."); } 

}

只有内部类可以声明为“静态”,请参阅下面的代码。 Upper / encapsulating类不能声明为“Static”。 它可以通过使用Upper / encapsulating类变量来访问.Static-inner-classname与使用类名的任何静态方法调用相同。

公共类StaticTest {

 public static void main(String ag[]){ System.out.println("hello...1"); StaticTest.StaticTest2.meth2(); } public static class StaticTest2 { public static void meth2(){ System.out.print("hello...2"); } } 

}

Abstract Class(Base class): 允许其他类inheritance此类( 一个类获取另一个类的属性(方法和字段) ),但禁止实例化, 即我们不能拥有此类的对象。 http://csharp.net-tutorials.com/classes/abstract-classes

静态类:此类无法实例化 。 此类也不能inheritance 。 要访问此类的方法,可以直接使用classname.method。 https://social.technet.microsoft.com/wiki/contents/articles/21028.difference-between-static-class-sealed-class-and-abstract-class-in-c.aspx

两者之间的主要区别在于可扩展性。

CLR将所有“静态”类标记为场景后面的“ 抽象和密封 ”(即,它们不能被inheritance,因此无法扩展),并且.NET Framework CLR在加载包含程序或命名空间时自动加载它们。 这样可以提高运行时的性能。

“抽象”类背后的哲学是将所有扩展类的所有共同特征都集中在一个地方。

希望能帮助到你。