c#面向对象中static 关键字
常用的的莫过于三大类:
静态类:类可以声明为 static 的,以指示它仅包含静态成员
public static class StaticClass { //1.不能被实例化 ,也不能被继承 // 2.仅仅包含静态成员 string name = "";这样是行不通滴,方法也是这样滴,总之: 静态类中不包含非静态成员; // 3. // /* 静态类和私有构造构造函数的区别: 1.私有构造函数依然可以从内部实例化对象, 而静态类禁止从任何地方实例化类,其中包括从类自身内部 */ }
实例分析A:
public class ClassA { public static string AppName = "hello, this is a static class test"; public static int num = 5; public ClassA() { num = 15; } public static int getNum() { return num; } }
在主函数中调用ClassA的静态方法
static void Main(string[] args) { int num=ClassA.getNum(); Console.WriteLine(num); Console.ReadLine(); }
最终的输出结果为:5
原因分析:
虽然有实例构造函数,但对classA类没有进行实例化,所以该实例构造函数没有被调用;
主函数代码修改如下:
static void Main(string[] args) { ClassA a = new ClassA(); int num=ClassA.getNum(); Console.WriteLine(num); Console.ReadLine(); }
输出结果为:15
如果类不声明为静态类(static class),很容易出现类似于上面的错误。修改为静态类
public static class ClassA { public static string AppName = "hello, this is a static class test"; public static int num = 5; static ClassA() { num = 15; } public static int getNum() { return num; } }
关于静态构造函数的补充:
(1) 静态构造函数不可继承;
(2) 静态构造函数可以用于静态类,也可用于非静态类;
(3) 静态构造函数无访问修饰符、无参数,只有一个 static 标志;
(4) 静态构造函数不可被直接调用,当创建类实例或引用任何静态成员之前,静态构造函数被自动执行,并且只执行一次。
实例分析B:如果是一个类中全部封装的是被外部调用的额方法,那么可以考虑将该类申明为static
public class sqlHelp { public void do1() { } public void do2() { } } public static class sqlHelper { public static void do1() { } public static void do2() { } } class Program { static void Main(string[] args) { //调用去方法 sqlHelp help = new sqlHelp(); help.do1(); sqlHelper.do1(); //终结:类没有属性,全是方法,那么,有必要为了调用类中的方法,先实例化一个对象出来吗? //省略了构造一个对象的性能损耗,虽然可以忽略不计。其次,对程序员比较友好,调用类的方法更加的方便。 } }
静态变量:
静态方法:
我们来看两道题!
第一题:
class Program { public static int i = 0; public Program() { int i = 1; Console.WriteLine("实例构造函数方法被调用"); } static Program() { i = 2; Console.WriteLine("静态构造函数被执行"); } static void Main(string[] args) { Console.WriteLine(Program.i); Program p = new Program(); Console.WriteLine(Program.i); } } }
答案:i为2,首先,类被加载,所有的静态成员被创建在静态存储区,i=0;接着调用了类的成员,这个时候静态构造函数别调用 i=2。
i为1,实例化后,调用构造函数,i=1,因为静态构造函数只执行一次,不能再被执行了。
第二题:
using System; namespace teststatic { class class1 { static int i = getNum(); int j = getNum(); static int num = 1; static int getNum() { return num; } static void Main(string[] args) { Console.WriteLine("i={0}",i); Console.WriteLine("j={0}", new class1().j); Console.Read(); } } }
Console.WriteLine(string.Format("i={0}",i)); 这里i是static变量,而且类class1是第一次被引 用,要先为class1里面所有的static变量分配内存。
指令在逻辑还是一条一条的按顺序执行的,所以 先为static int i分配内存,并且在该内存中保持int的缺省值0,接着再为static int num 变量分配内存,
值当然也为0。
然后执行第二步,
为变量赋值:先为static int i变量赋值,i=getNum(),
看getNum里面的代码,就是return num,这个时候num的值是0,
于是i就为0了。然后对变量num赋值,num=1;这行代码执行后,
num就为1了。
所以最后的结果为:
i=0 j=1