2010-03-06 75 views
23

两者都不可实例化。有什么区别,在哪些情况下你可以使用其中一种?抽象类和静态类之间有什么区别?

+2

记住在使用静态类时要考虑线程安全性。 [see here](http://stackoverflow.com/questions/1090650/are-static-methods-thread-safe) – kenchilada 2013-07-08 14:44:58

回答

19

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

Here's more detail on using static members and classes

abstract s定义了所有派生类型共享的基本结构和功能,但不能单独使用。我想,把它们想象成蓝图和合同。这是面向对象的核心概念。

Here's more detail on using abstracts

+3

c#中的一个静态类是一个密封的抽象类 – 2016-09-21 17:00:35

2

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

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

15

这里是一个简短的总结:

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

的主要区别是,你可以从abstract类继承,但你不能从一个static类继承。从技术上讲,.NET运行时没有任何static类的概念,所以C#编译器将它们作为abstractsealed(意味着您不能从它们继承)的类来遵守它们。

所以,staticabstract类,也sealed(虽然这不是看待这个问题,如果你是C#程序员通常的方式),并且只包含static成员(由C#编译器执行)。

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); 
} 

在这里,用户的缓存是一种常见的关注,在基本情况下为蓝本,而实际retreival留给子类来提供。

静态类是完全不同的事情。他们基本上是保持你的实用功能的地方:

static class StrUtil { 

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

把它们当作某种特殊的命名空间,它只能包含静态成员。基本上是放置功能的地方。

7

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

静态类用于单态或无状态功能。抽象类不适用于单例功能,因为即使它可能包含静态方法和字段,但它不能禁止继承,所以单例使用可能会被子类击败。或者,至少它会让其他程序员感到困惑,因为它的定义会传达一个与其实际使用目的不同的意图。

抽象类和静态类之间的表面相似性仅在于两者都不可实例化。除此之外,它们是完全不同的使用情况完全不同的动物。

6

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

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

制作它的密封是非常静态类的点,它被用作静态方法和字段的容器。这使得它们像全局变量和函数一样行事,就像你在C或Pascal等语言中一样。

抽象类非常相反,它被设计为派生自。抽象类具有全部其成员抽象行为就像一个接口。 C#有一个关键字,使静态类和接口成为完全相反的对象。

+0

+1用于指出静态类是密封的,在引擎盖下抽象。 – Firestrand 2010-03-06 03:38:16

1

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

但是,它也可以在没有实现任何抽象方法的情况下声明一个类为“Abstract”。请参阅下面的示例。

公共抽象类AbstractTest {

public void abcd(){} 

public static void main(String[] args) { 

     System.out.print("hi..."); 

} 

}

只有内部类可以声明为 “静态”,请参见下面的代码。 上层/封装类不能声明为“静态”。 可以通过使用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"); 
    } 
} 

}两者之间

-1

主要区别是可扩展性。

CLR马克所有“静态”类为“抽象&密封”幕后(即,它们不能因此继承不能延长)和含有节目或命名空间时,会自动.NET框架CLR加载它们加载。这会在运行时带来性能提升。

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

希望它有帮助。

相关问题