C# 静态成员、静态方法、静态类、实例成员及区别
文章目录
1.静态成员、实例成员
2.静态类
3.类的静态成员和非静态成员区别
4.静态与非静态方法的比较
--------------------------------------分割线---------------------------------------------
1.静态成员、实例成员
1.1定义及说明
数据成员:
静态成员:静态成员变量是和类相关联的,可以作为类中"共"有的变量(是一个共性的表现),他不依赖特定对象的存在,访问的时候通过类名加点操作符加变量名来访问.
实例成员:实例成员变量是和对象相关联的,访问实例成员变量依赖于实例的存在.
函数成员:
静态方法:静态方法是不属于特定对象的方法,静态方法可以访问静态成员变量和静态方法;静态方法不可以直接访问实例变量和实例方法,可以间接调用,首先要创建一个类的实例,然后通过这一特定对象来调用静态方法;
实例方法:一个实例方法的执行与特定对象关联,他的执行需要一个对象存在。实例方法可以直接访问静态变量和实例变量,当多个实例对象存在时,内存中并不是存在美个特定的实例方法的拷贝,而是,相同类的所有对象都共享每个实例方法的一个拷贝(实例方法只占用“一套”空间)。
| 静态成员变量 | 静态方法 | 实例成员变量 | 实例方法 | |
| 静态方法 | 直接访问 | 直接访问 | 不可直接访问 | 不可直接访问 |
| 实例方法 | 直接访问 | 直接访问 | 直接访问 | 直接访问 |
总之:实例方法的存在必须要有对象实例的存在,如果对象实例不存在,则实例方法也就没有调用它的主人。静态方法的存在前提是类的存在,所以无需声明和New对象。
1.2代码演示
1 class Program 2 { 3 4 static void Main(string[] args) 5 { 6 Class1.CallObjectFunc();//静态调用 7 8 Console.WriteLine(Environment.NewLine); 9 10 Class1 tmpClass = new Class1();//实例调用 11 tmpClass.ObjectFunc(); 12 13 Console.ReadKey(); 14 } 15 } 16 17 class Class1 18 { 19 static int Class_m = 9;//静态成员 20 private int object_m = 8;//实例成员 21 22 public static void CallObjectFunc() 23 { 24 Console.WriteLine("------------静态方法调用开始:"); 25 26 Class1 class1 = new Class1(); 27 class1.ObjectFunc(); 28 Console.WriteLine("object_m:" + class1.object_m.ToString()); 29 30 Console.WriteLine("------------静态方法调用结束:"); 31 } 32 33 public void ObjectFunc() 34 { 35 Console.WriteLine("实例方法调用开始:"); 36 37 Console.WriteLine("Class_m:" + Class_m.ToString()); 38 39 Console.WriteLine("实例方法调用结束:"); 40 } 41 }
输出结果:

2.静态类
静态类的主要功能如下:
-
它们仅包含静态成员。----函数成员和变量都必须有static修饰
-
它们不能被实例化。
-
它们是密封的。-----------编译器编译时自动生成sealed标记
-
它们不能包含实例构造函数。
因此创建静态类与创建仅包含静态成员和私有构造函数的类大致一样。私有构造函数阻止类被实例化。
使用静态类的优点在于,编译器能够执行检查以确保不致偶然地添加实例成员。编译器将保证不会创建此类的实利。
静态类是密封的,因此不可被继承。静态类不能包含构造函数,但仍可声明静态构造函数以分配初始值或设置某个静态状态。
静态类:
static class CompanyInfo { public static string GetCompanyName() { return "CompanyName"; } public static string GetCompanyAddress() { return "CompanyAddress"; } }
3.类的静态成员和非静态成员区别
3.1区别
(1)语法区别:静态成员有关键字static,非静态成员无static修饰;
(2)存储区别: 静态成员变量存储位于程序的全局变量存储区,其作用域限制为类内部,并且在整个程序运行期间只在内存中拥有一个存储位置,不会拷贝不会复制,只是一个;
非静态成员变量存储位于对象的变量存储区,多个对象拥有多个变量的存储,只隶属于自己的的对象
(3)归属区别:静态成员隶属于类,是类的财产,无论对一个类创建多少个实例,它的静态成员都只有一个副本,在各个地方的改变都会改变其值;
非静态成员隶属于它的对象,各自对象同一个非静态成员值的改变都不互相影响,有多少实例就有多少副本;
(4)生存周期区别: 知道了存储位置的区别也就不难理解生存周期的差异了,静态成员只要分配了空间则在整个程序运行期间,它都是存在的,只有程序关闭之后,它的内存才会被GC回收器收回,不过作用域仍然只限制于类的内部,在类外部调用时需要使用类 名加点的方式访问;
类的非静态成员的生存周期跟随于隶属于对象的生存周期,对象消亡则非静态成员就会被回收;
(5)初始化顺序的区别:初始化都是最先初始化类的静态成员,然后才是非静态数据成员。
3.2代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 class class1 7 { 8 private static int i = getNum(); 9 private static int num = 1; 10 11 int j = getNum(); 12 13 private static int getNum() 14 { 15 return num; 16 } 17 18 static void Main(string[] args) 19 { 20 Console.WriteLine("i={0}", i); 21 22 class1 class1Object = new class1();//默认构造函数 23 Console.WriteLine("j={0}", class1Object.j); 24 Console.WriteLine("i={0}", i); 25 26 Console.ReadKey(); 27 } 28 }

代码分析
类结构:这个类有三个变量,两个私有静态成员变量i和j,一个非静态成员变量num;一个私有静态函数getNum(),一个函数入口Main()
程序执行过程:首先之前说了初始化会首先初始化类的静态变量。
i分配空间并初始化值为0-->num分配空间并初始化为0-->i赋值(调用getNum函数,此时num为0,返回值为0,所以i=0)-->num赋值为1-->Main函数
至于Main函数内执行时,为什么i输出不是1呢?这是因为静态成员只初始化一次,所以此时调用i并不会再调用getNum()函数为其赋值,此时的调用i是获取i分配空间上的值。
C#静态方法与非静态方法比较一:
C#静态成员:
①静态成员属于类所有,非静态成员属于类的实例所有。
②每创建一个类的实例,都会在内存中为非静态成员新分配一块存储;
静态成员属于类所有,为各个类的实例所公用,无论类创建了多少实例,类的静态成员在内存中只占同一块区域。
C#静态方法与非静态方法比较二:
C#静态方法
1、C#静态方法属于类所有,类实例化前即可使用。
2、非静态方法可以访问类中的任何成员,静态方法只能访问类中的静态成员。
3、因为静态方法在类实例化前就可以使用,而类中的非静态变量必须在实例化之后才能分配内存,(静态方法在类实例化前就可使用,在类被实例化之前,非静态变量根本就不存在,无法调用)
这样,C#静态方法调用时无法判断非静态变量使用的内存地址。所以无法使用。而静态变量的地址对类来说是固定的,故可以使用。
C#静态方法与非静态方法比较三:
C#静态方法是一种特殊的成员方法 它不属于类的某一个具体的实例,而是属于类本身。所以对静态方法不需要首先创建一个类的实例,而是采用类名.静态方法的格式 。
1.static方法是类中的一个成员方法,属于整个类,即不用创建任何对象也可以直接调用!
static内部只能出现static变量和其他static方法!而且static方法中还不能使用this....等关键字..因为它是属于整个类!
2.静态方法效率上要比实例化高,静态方法的缺点是不自动进行销毁,而实例化的则可以做销毁。
3.静态方法和静态变量创建后始终使用同一块内存,而使用实例的方式会创建多个内存.
4.C#中的方法有两种:实例方法,静态方法.
C#静态方法与非静态方法比较四:
C#静态方法中获取类的名称
静态方法中用:
string className = System.Reflection.MethodBase.GetCurrentMethod().ReflectedType.FullName;
非静态方法中还可以用:
string className = this.GetType().FullName;
转自:http://www.cnblogs.com/Matcha/p/5312268.html
浙公网安备 33010602011771号