• 静态类与非静态类


    静态类

      继承(多态)、静态本身就是相反的。另外需要知道属性、事件其实是些特殊的方法。

      使用 static 修饰符声明属于类型本身而不是属于特定对象的静态成员。 static 修饰符可用于类、字段、方法、属性、运算符、事件和构造函数,但不能用于索引器、析构函数或类以外的类型。

      静态类与非静态类基本相同,但存在一个区别:静态类不能实例化。 也就是说,不能使用 new 关键字创建静态类类型的变量。 因为没有实例变量,所以要使用类名本身访问静态类的成员

      对于 只对输入参数进行运算 而不获取或设置 任何内部实例字段的方法集,静态类可以方便地用作这些方法集的容器。 例如,在 .NET Framework 类库中,静态类 System.Math 包含的方法只执行数学运算,而无需存储或检索特定 Math 类实例特有的数据。 就是说,通过指定类名称和方法名称来应用类成员。

      和所有类类型一样,当加载引用静态类的程序时,.NET Framework 公共语言运行时 (CLR) 将加载该静态类的类型信息。程序不能指定加载静态类的确切时间。 但是,可以保证在程序中首次引用该类前加载该类,并初始化该类的字段并调用其静态构造函数。 静态构造函数仅调用一次,在程序驻留的应用程序域的生存期内,静态类一直保留在内存中。

    下表介绍静态类的主要特性:

    • 仅包含静态成员。
    • 无法实例化。
    • 是密封的。
    • 不能包含实例构造函数。

      因此,创建静态类与创建仅包含静态成员和私有构造函数的类基本相同。 私有构造函数阻止类被实例化。使用静态类的优点在于,编译器能够执行检查以确保不致偶然地添加实例成员。编译器将保证不会创建此类的实例。

      静态类是密封的,因此不可被继承。 它们不能从除 Object 外的任何类中继承。 静态类不能包含实例构造函数,但可以包含静态构造函数。 如果非静态类包含需要进行重要的初始化的静态成员,也应定义静态构造函数。

    静态类构造函数

      静态构造函数用于初始化任何 静态 数据,或用于执行仅需执行一次的特定操作。 在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数。

    例如:

    class SimpleClass

    {   static readonly long baseline;

        static SimpleClass()

        { baseline = DateTime.Now.Ticks; }

    }

      静态构造函数具有以下特点:

    • 静态构造函数既没有访问修饰符,也没有参数。
    • 在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数来初始化类。
    • 无法直接调用静态构造函数。
    • 在程序中,用户无法控制何时执行静态构造函数。
    • 静态构造函数的典型用途是:当类使用日志文件时,将使用这种构造函数向日志文件中写入项。
    • 静态构造函数在为非托管代码创建包装类时也很有用,此时该构造函数可以调用 LoadLibrary 方法。
    • 如果静态构造函数引发异常,运行时将不会再次调用该构造函数,并且在程序运行所在的应用程序域的生存期内,类型将保持未初始化。

    静态成员

      非静态类可以包含静态的方法、字段、属性或事件。 即使没有创建类的实例,也可以调用该类中的静态成员。 始终通过类名而不是实例名称访问静态成员。 无论对一个类创建多少个实例,它的静态成员都只有一个副本。 静态方法和属性不能访问其包含类型中的非静态字段和事件,并且不能访问任何对象的实例变量(除非在方法参数中显式传递)。

      更常见的做法是声明具有一些静态成员的非静态类,而不是将整个类声明为静态类。 静态字段有两个常见的用法:一是记录已实例化对象的个数,二是存储必须在所有实例之间共享的值。

      静态方法可以被重载但不能被重写,因为它们属于类,不属于类的任何实例。

      虽然字段不能声明为 static const,但 const 字段的行为在本质上是静态的。 这样的字段属于类型,不属于类型的实例。

      C# 不支持静态局部变量(在方法范围内声明的变量)。

      通过在成员的返回类型之前使用 static 关键字可以声明静态类成员,也就是在方法的返回类型前加static。

      静态成员在第一次被访问之前并且在调用静态构造函数(如有存在)之前进行初始化。 若要访问静态类成员,应使用类名而不是变量名来指定该成员的位置。

    自问自答,自娱自乐

      静态成员与实例成员的性能对比和生成调用指令的差别有哪些?

      对静态方法的调用以 Microsoft 中间语言 (MSIL) 生成调用指令,而对实例方法的调用生成 callvirt 指令,该指令还检查 null 对象引用。 但是,两者之间的性能差异在大多数时候并不明显。

      为什么静态类不能被继承?

      经反编译查看,Static内部是用sealed和abstract两个关键字组合实现的,也就是说没有static这个关键字,只是为了方便区别。

      静态类的使用和实例类中静态成员的使用技巧?

      对于 只对输入参数进行运算 而不获取或设置 任何内部实例字段的方法集,静态类可以方便地用作这些方法集的容器。也就是说,这个类只是一个工具类,里面都是些方法。

      常见的做法是声明具有一些静态成员的非静态类,而不是将整个类声明为静态类。由于无论对一个类创建多少个实例,它的静态成员都只有一个副本,所以静态字段有两个常见的用法:一是记录已实例化对象的个数,二是存储必须在所有实例之间共享的值。

      静态类和非静态类之间的包含关系?

      非静态类可以包含静态类成员,静态类只能包含静态成员。如下所示:

      Static class staticclass{//只能是静态成员};

      Class newClass{//可以包含静态成员};

      尽管类的实例包含该类所有实例字段的单独副本,但每个静态字段只有一个副本。

     静态类成员声明字段的特殊性:

    class Test

    {  static int x = y;

       static int y = 5;

       static void Main() {

          Console.WriteLine(Test.x);

          Console.WriteLine(Test.y);

          Test.x = 99;

          Console.WriteLine(Test.x);}

    }/*Output: 0  5  99  */

      什么情况下需要在一个普通类中编写一个静态成员,而这个类不能标记static?

      当这个需要被实例化的时候,如果这个类中有一个成员是所有对象都共享的数据,这时可以将该类中的这个成员标记为静态的,但是这个类还是一个实例类。

    特别需要注意的有哪些呢?   

    1. 静态成员会在整个应用程序退出时,才释放资源,所以可以在整个应用程序中共享数据。
    2. 当一个普通类添加静态字段后,系统会默认为该类生成一个静态构造函数【静态构找函数不能有访问修饰符,并且也不能带参数】
    3. 静态方法可以被重载但不能被重写,因为它们属于类,不属于类的任何实例。
    4. 不可以使用 this 来引用静态方法或属性访问器。
    5. 类和静态类可以有静态构造函数。 静态构造函数在程序开始和类实例化之间的某个时刻调用。
    6. 静态类的本质是abstract+sealed组成。静态类不能被实例化是因为abstract,不能被继承是因为sealed。
  • 相关阅读:
    ACM-ICPC 中可能会使用到的库
    ACM中java的使用
    Codeforces
    洛谷 P1879 玉米田(状压DP入门题)
    洛谷 P2622 关灯问题II(状压DP入门题)
    poj 2385 Apple Catching(记录结果再利用的动态规划)
    NOIP 提高组 2014 飞扬的小鸟(记录结果再利用的DP)
    2018.10.26 浪在ACM 集训队第四次测试赛
    NOIP 提高组 2014 联合权值(图论???)
    NOIP 普及组 2012 寻宝(思维???)
  • 原文地址:https://www.cnblogs.com/anlen/p/3723269.html
Copyright © 2020-2023  润新知