两者都不可实现。有什么区别,在什么情况下你可能会使用其中一种?
答案 0 :(得分:27)
static
表示该类只能有静态成员,您无法创建它的实例。这用于无状态功能(例如,仅定义扩展方法或实用程序方法的类型)。您还可以在非静态类上声明成员static
。这允许您将功能附加到类型而无需实例化它。
Here's more detail on using static members and classes。
abstract
定义了所有派生类型共享的基本结构和功能,但不能单独使用。我认为,将它们视为蓝图和合同。这是OOP的核心概念。
答案 1 :(得分:21)
以下是简短摘要:
static
个成员(它只是一个逻辑上不属于任何标准类实例的方法的容器)关键区别在于您可以从abstract
类继承,但不能从static
类继承。从技术上讲,.NET运行时没有任何static
类的概念,因此C#编译器将它们编译为abstract
和sealed
的类(意味着你不能继承自它们)。
因此,static
类是abstract
类也是sealed
(尽管如果你是C#程序员,这不是查看问题的常用方法)并且只包含{{成员(由C#编译器强制执行)。
答案 2 :(得分:7)
抽象类旨在用作类继承层次结构的基础。静态类不能成为类继承层次结构的基础。
静态类用于单例状态或无状态功能。抽象类不适用于单例功能,因为即使它可能包含静态方法和字段作为静态类,它也不能禁止继承,因此单例使用可能会被子类击败。或者,至少,它会让其他程序员感到困惑,因为它的定义会传达一个与其实际用途不同的意图。
抽象类和静态类之间的表面相似之处仅在于它们都不能被实例化。除此之外,它们是完全不同的动物,具有完全不同的用例。
答案 3 :(得分:6)
CLR没有静态类的概念,它特定于C#。编译器通过为类使用CLR属性来实现它:它声明它抽象和密封。这可以防止任何语言实例化这样的类。这就是你运行Ildasm时的样子:
.class public abstract auto ansi sealed beforefieldinit ConsoleApplication1.Test
extends [mscorlib]System.Object
{
}
使其密封非常重要的是静态类,它被用作静态方法和字段的容器。这使得它们像C或Pascal等语言一样充当全局变量和函数。
抽象类恰恰相反,它的设计源于。具有所有其成员抽象的抽象类就像一个接口。 C#有一个关键字,使静态类和接口完全相反。
答案 4 :(得分:2)
抽象类通过派生类间接实例化。它们提供了常见的行为和实例状态,但表明需要更多,并且必须由派生的具体类提供。例如,Transform
可能是一个抽象类:它声明了一个公共Apply(Shape)
方法,但没有实现该方法。像Rotation
或Translation
这样的具体派生类将实现该方法,并且可以实例化这些类。
无法实例化静态类,并且任何状态都在类级别而不是实例级别。它们通常用于定义实用程序方法,其中没有与方法关联的状态。 Transform
不能是静态类,因为具体派生类需要每个实例状态(例如Rotation
需要每个实例Angle
,因为不同的Rotation
转换可以从不同的角度来看。)
答案 5 :(得分:2)
抽象类旨在用作基类;他们不能有直接的实例。相反,您必须派生子类,它提供抽象基类中(通常是故意的)遗漏的内容。
示例:假设您有一个复杂的应用程序,用户可以登录到该应用程序。应该使用各种身份验证机制,例如LDAP,NTLM,您可以使用它。在这样的上下文中建模“用户”或“主体”的一种方法是将所有这些机制中的共同点收集到抽象基类中,并将“间隙”(抽象方法)留在实际实现中发挥:
abstract class Authenticator {
protected Dictionary<string,User> 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);
}
在这里,用户的缓存是一个常见的问题,在基本情况下建模,而实际的撤销是留给子类提供的。
静态类是完全不同的事情。它们本质上是一个保持实用功能的地方:
static class StrUtil {
public static string TrimWhitespace(string str) {
...
}
}
将它们视为某种特殊的命名空间,它只能包含静态成员。基本上,放置功能的地方。
答案 6 :(得分:1)
抽象类的主要目的是定义一个或多个抽象方法。 任何扩展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,与使用类名的任何静态方法调用相同。
public class 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");
}
}
}
答案 7 :(得分:1)
抽象类(基类): 允许其他类从此类继承 (一个类获取另一个的属性(方法和字段)),但 禁止实例化 即我们不能拥有此类的对象。 http://csharp.net-tutorials.com/classes/abstract-classes
静态类: 此类 无法实例化 。此 类也无法继承 。要访问此类的方法,可以直接使用classname.method。 https://social.technet.microsoft.com/wiki/contents/articles/21028.difference-between-static-class-sealed-class-and-abstract-class-in-c.aspx
答案 8 :(得分:-1)
两者之间的主要区别在于可扩展性。
CLR 将所有'静态'类标记为' abstract&amp;在场景后面密封'(即,它们不能被继承,因此无法扩展),并且.NET Framework CLR在加载包含程序或命名空间时自动加载它们。这样可以提高运行时的性能。
“抽象”类背后的哲学是将所有扩展类的所有共同特征都集中在一个地方。
希望它有所帮助。