CS3L8——静态成员

本章代码关键字

1
2
static        //用static修饰的成员为静态成员,静态成员在程序开始时就会被分配内存空间,直到程序运行结束才会被释放,可以直接点出使用
const //可以理解为特殊的static,相比static,它必须初始化,也不可改变

静态成员

静态关键字 static​,用 static​ 修饰的 成员变量、方法、属性等,称为静态成员

静态成员的特点是:直接用 类名.静态成员​ 就可以使用
静态成员在程序开始时就会被分配内存空间,直到程序运行结束才会被释放

注意:静态函数中不能直接使用非静态成员,非静态函数中可以直接使用静态成员

​const​(常量)可以理解为特殊的 static​(静态)

静态关键字 static​ 还可以修饰类和构造函数,详见:CS3L9——静态类和静态构造函数

早已出现的静态成员

类似于 Console.WriteLine()​ 这些函数都是早已出现并被我们使用的静态函数

自定义静态成员

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Test
{
public static float PI = 3.1415926f; //静态成员变量,访问修饰符和static的顺序是随意的
public int testInt = 100; //成员变量


public static float CalcCircle(float r) //静态成员方法
{
return PI * r * r;
}


public void TestFun() //成员方法
{
Console.WriteLine("123");
}
}

静态成员的使用

静态成员变量和静态成员方法无需实例化即可使用,而非静态的成员变量和成员方法必须要实例化才可以使用

注意,静态成员变量和静态成员方法是不能通过实例化来使用的!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Test
{
public static float PI = 3.1415926f; //静态成员变量,访问修饰符和static的顺序是随意的
public int testInt = 100; //成员变量


public static float CalcCircle(float r) //静态成员方法
{
return PI * r * r;
}


public void TestFun() //成员方法
{
Console.WriteLine("123");
}
}

internal class Program
{
static void Main(string[] args)
{
// 静态成员变量和静态成员方法无需实例化即可使用
Console.WriteLine(Test.PI);
Console.WriteLine(Test.CalcCircle(2));

// 非静态的成员变量和成员方法必须要实例化才可以使用
Test t = new Test();
Console.WriteLine(t.testInt);
t.TestFun();

// 注意,静态成员变量和静态成员方法是不能通过实例化来使用的!!!
//Console.WriteLine(t.PI);
//t.CalcCircle();
}
}

静态成员不实例化即可直接使用的原因

记住,程序不能无中生有,我们要使用的对象,变量,函数都是要在内存中分配内存空间的
之所以要实例化对象 目的计算要分配内存空间 在程序中产生一个抽象的对象

而静态成员的特点是:静态成员在程序开始运行时,就会直接被分配内存空间,所以我们可以直接使用
静态成员的存在 是和 程序运行的状态 是绑定的,程序运行则静态成员就一直存在在内存内

只要使用静态成员,静态成员的分配的内存 直到程序结束才会被释放
所以一个静态成员就会有 一个自己唯一一个“内存空间”,这使得静态成员具有唯一性

在任何地方使用静态成员, 都是使用该静态成员唯一的“内存空间”,
改变了静态变量,也是改变该“内存空间”的内容
因此,public​ 的静态成员具有全局性

静态函数中不能使用非静态成员

静态成员方法内不能直接使用 非静态成员 否则会报错,因为非静态成员必须要实例化后才能使用
成员变量只能将对象实例化出来后才可以使用,不能无中生有

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Test
{
public static float PI = 3.1415926f; //静态成员变量,访问修饰符和static的顺序是随意的
public int testInt = 100; //成员变量

//静态成员方法
public static float CalcCircle(float r)
{
//Console.WriteLine(testInt); //静态成员方法内不能直接使用 非静态成员 否则会报错,因为非静态成员必须要实例化后才能使用
Test t = new Test();
Console.WriteLine(t.testInt); //成员变量只能将对象实例化出来后才可以使用,不能无中生有
return PI * r * r;
}
}

非静态函数可以使用静态成员

因为静态成员在程序开始时就存在了,所以可以直接使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Test
{
public static float PI = 3.1415926f; //静态成员变量,访问修饰符和static的顺序是随意的
public int testInt = 100; //成员变量


public static float CalcCircle(float r) //静态成员方法
{
//Console.WriteLine(testInt); //静态成员方法内不能直接使用 非静态成员 否则会报错,因为非静态成员必须要实例化后才能使用
Test t = new Test();
Console.WriteLine(t.testInt); //成员变量只能将对象实例化出来后才可以使用,不能无中生有
return PI * r * r;
}

public void TestFun() //成员方法
{
Console.WriteLine("123");
Console.WriteLine(CalcCircle(100));
Console.WriteLine(PI);
}
}

静态成员对于我们的作用

  • 静态变量:多用于常用的唯一变量申明,方便别人获取的对象申明
  • 静态方法:常用的唯一的方法申明,例如:相同规则的数学计算相关函数

静态的缺点:滥用静态变量会大量挤占一般变量,方法等的内存
导致可分配的内存空间变少,容易频繁触发GC,导致程序性能严重下降

因此静态变量和静态方法要慎重使用!!!

常量和静态变量

​const​(常量)可以理解为特殊的 static​(静态)

  • 相同点:他们都可以通过类名点出使用

  • 不同点:

    • const​ 必须初始化,不能修改,static​ 没有这个规则
    • const​ 只能修饰变量,static​ 可以修饰很多内容
    • const​ 一定写在访问修饰符后面,static​ 没有这个规则
1
2
3
4
5
class Test
{
public static float PI; //可以不初始化,可以修改
public const float G = 9.8f; //必须初始化,不可修改
}