9.面向对象-封装-静态成员
9.1 知识点
知识回顾
class 类名
{
#region 特征——成员变量
#endregion
#region 行为——成员方法
#endregion
#region 初始化调用——构造函数
#endregion
#region 释放时调用——析构函数
#endregion
#region 包裹成员变量——成员属性
#endregion
#region 通过中括号使用对象——索引器
#endregion
}
静态成员基本概念
static
关键字用于修饰成员变量、方法、属性等,称为静态成员。- 静态成员的特点是:直接用类名点出使用。
早已出现的静态成员
- 静态成员早在
Console
类中就已经出现,例如属性和方法。
自定义静态成员
class Test
{
// 静态成员变量
static public float PI = 3.1415926f;
// public 和 static 的顺序可以随意摆放
public static float π = 3.1415926f;
// 成员变量
public int testInt = 100;
// 静态成员方法
public static float CalcCircle(float r)
{
// πr²
return PI * r * r;
}
// 成员方法
public void TestFun()
{
Console.WriteLine("123");
}
}
静态成员的使用
主函数内
- 使用静态成员
// 输出静态成员变量 π Console.WriteLine(Test.PI); // 3.1415925 Console.WriteLine(Test.π); // 3.1415925 // 半径为2的圆的面积 Console.WriteLine(Test.CalcCircle(2)); // 12.56637
- 实例化对象后使用非静态成员
Test t = new Test(); Console.WriteLine(t.testInt); // 100 t.TestFun(); // 123
- 实例化对象不能使用静态成员
// Console.WriteLine(t.PI); // 报错 // Console.WriteLine(t.CalcCircle(2)); // 报错 // 无法使用实例引用访问静态成员“member”;用类型名称限定它。 // 只能使用类名来限定静态变量;实例名称不能是限定词。
为什么可以直接点出来使用
- 实例化对象的特点:对象、变量、函数都需要在内存中分配内存空间。
- 静态成员的特点:程序开始运行时就会分配内存空间,因此可以直接使用。
静态函数中不能使用非静态成员
public static float CalcCircle(float r)
{
// 静态函数中不能使用非静态成员
// Console.WriteLine(testInt); // 报错,非静态字段、方法或属性“成员”需要对象引用。
// 非静态成员不能无中生有,必须通过对象实例化后才能访问
Test t = new Test();
t.testInt = 54250;
Console.WriteLine("CalcCircle实例化对象后,输出testInt的值是:{0}", t.testInt);
// πr²
return PI * r * r;
}
非静态函数可以使用静态成员
public void TestFun()
{
Console.WriteLine("123");
// 非静态函数可以使用静态成员
// 静态成员的生命周期比非静态更长,因此在非静态函数中使用静态成员没有问题
Console.WriteLine("非静态函数可以使用静态成员" + "PI:" + PI);
// 使用静态成员方法也没有问题
Console.WriteLine("非静态函数可以使用静态成员" + "CalcCircle(2):" + CalcCircle(2));
}
静态成员对于我们的作用
静态变量的作用:
- 常用唯一变量的声明,如 π。
- 方便别人获取的对象声明,静态变量具有全局性。
静态方法的作用:
- 常用的唯一的方法声明,例如相同规则的数学计算相关函数,如圆的周长和面积。
过多的静态成员的后果:
- 过多的静态成员可能导致频繁触发 GC。
常量和静态变量
const
(常量)可以理解为特殊的static
(静态)。- 常量和静态变量的相同点:它们都可以通过类名点出使用。
- 常量和静态变量的不同点:
const
必须初始化,不能修改;static
没有这个规则。const
只能修饰变量,static
可以修饰很多。const
一定是写在访问修饰符后面的,static
没有这个规则。
测试类内
// 常量
// 重力加速度
public const float G = 9.8f;
// 一定要初始化,否则报错
// 自然对数
// const public float e = 2.72f;
// 报错,const 一定是写在访问修饰符后面的
主函数内
// Test.G = 10; // 报错,常量不可修改
Console.WriteLine(Test.G); // 9.8
总结
- 概念:用
static
修饰的成员变量、成员方法、成员属性等就称为静态成员。 - 特点:直接用类名点出来使用(全局性)。
- 生命周期:和程序同生共死,程序运行后就会一直存在内存中,直到程序结束后才会释放,因此静态成员具有唯一性。
- 注意:
- 静态函数中不能直接使用非静态成员。
- 非静态函数中可以直接使用静态成员。
- 常量和静态变量:
- 常量是特殊的静态变量。
- 常量和静态变量相同点:它们都可以通过类名点出来使用。
- 常量和静态变量不同点:
const
必须初始化,不能被修改;static
没有这个规则。const
只能修饰变量,static
可以修饰很多。const
不能写在访问修饰符前面,一定是写在变量声明前面;static
没有这个规则。
9.2 知识点代码
using System;
namespace Lesson7_封装_静态成员
{
#region 知识回顾
class 类名
{
#region 特征——成员变量
#endregion
#region 行为——成员方法
#endregion
#region 初始化调用——构造函数
#endregion
#region 释放时调用——析构函数
#endregion
#region 包裹成员变量——成员属性
#endregion
#region 通过中括号使用对象——索引器
#endregion
}
#endregion
#region 知识点一 静态成员基本概念
//静态关键字 static
//用static修饰的 成员变量、方法、属性等 称为静态成员
//静态成员的特点是:直接用类名点出使用
#endregion
#region 知识点二 早已出现的静态成员
//如 Console类里出现的属性和方法
#endregion
#region 知识点三 自定义静态成员
//class语句块外 语句块内
// 测试 类
class Test
{
//静态成员变量
static public float PI = 3.1415926f;
//public 和 static 的顺序可以随意摆放
public static float π = 3.1415926f;
//成员变量
public int testInt = 100;
//静态成员方法
public static float CalcCircle(float r)
{
#region 知识点六 静态函数中不能使用非静态成员
//成员变量只能将对象实例化出来后 才能点出来使用 不能无中生有
//不能直接使用 非静态成员 否则会报错
//Console.WriteLine(testInt);
//报错 非静态字段、方法或属性“成员”需要对象引用
//非静态成员不能无中生有
//一定要打印testInt的话可以实例化一个对象出来
Test t = new Test();
t.testInt = 54250;
Console.WriteLine("CalcCircle实例化对象后,输出testInt的值是:{0}",t.testInt);
//CalcCircle实例化对象后,输出testInt的值是:54250
#endregion
//πr²
return PI * r * r;
}
//成员方法
public void TestFun()
{
Console.WriteLine("123");
#region 知识点七 非静态函数可以使用静态成员
//静态成员生命周期比非静态更长一点
//所以非静态里使用静态成员没有问题
Console.WriteLine("非静态函数可以使用静态成员" + "PI:" + PI);
//非静态函数可以使用静态成员PI:3.1415925
//使用静态成员方法也没有问题
Console.WriteLine("非静态函数可以使用静态成员" + "CalcCircle(2):" + CalcCircle(2));
//非静态函数可以使用静态成员CalcCircle(2):12.56637
#endregion
}
#region 知识点九 常量和静态变量
// 测试类 内
//常量
//重力加速度
public const float G = 9.8f;
//一定要初始化 否则报错
//自然对数
//const public float e = 2.72f;
//报错 const一定是写在访问修饰符后面的
#endregion
}
#endregion
#region 知识点五 为什么可以直接点出来使用
//实例化对象的特点
//程序中是不能无中生有的
//我们要使用的对象,变量,函数都是要在内存中分配内存空间的
//之所以要实例化对象,目的就是分配内存空间,在程序中产生一个抽象的对象
//静态成员的特点
//程序开始运行时 就会分配内存空间。所以我们就能直接使用。
//静态成员和程序同生共死
//只要使用了它,直到程序结束时内存空间才会被释放
//所以一个静态成员就会有自己唯一的一个“内存小房间”
//这让静态成员就有了唯一性
//在任何地方使用都是用的小房间里的内容,改变了它也是改变小房间里的内容
//所以同时具有全局性
#endregion
#region 知识点八 静态成员对于我们的作用
//静态变量的作用:
//1.常用唯一变量的申明 如π
//2.方便别人获取的对象申明 静态变量具有全局性
//静态方法的作用:
//常用的唯一的方法申明
//比如 相同规则的数学计算相关函数
//例:圆的周长和面积
//过多的静态成员 可能导致频繁触发GC
#endregion
#region 知识点九 常量和静态变量
//const(常量)可以理解为特殊的static(静态)
//常量和静态变量的相同点
//他们都可以通过类名点出使用
//常量和静态变量的不同点
//1.const必须初始化,不能修改 static没有这个规则
//2.const只能修饰变量、static可以修饰很多
//3.const一定是写在访问修饰符后面的 ,static没有这个要求
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("静态成员");
//主函数内
#region 知识点四 静态成员的使用
//使用静态成员
//输出静态成员变量 π
Console.WriteLine(Test.PI);//3.1415925
Console.WriteLine(Test.π);//3.1415925
//半径为2的圆的面积
Console.WriteLine(Test.CalcCircle(2));//12.56637
//实例化对象后使用非静态成员
Test t = new Test();
Console.WriteLine(t.testInt);//100
t.TestFun();//123
//实例化对象不能使用静态成员
//Console.WriteLine(t.PI);//报错
//Console.WriteLine(t.CalcCircle(2));//报错
//无法使用实例引用访问静态成员“member”;用类型名称限定它
//只能使用类名来限定静态变量;实例名称不能是限定词。
#endregion
#region 知识点九 常量和静态变量
//Test.G = 10;//报错 常量不可修改
Console.WriteLine(Test.G);//9.8
#endregion
}
}
//总结
//概念:用static修饰的成员变量、成员方法、成员属性等 就称为静态成员
//特点:直接用类名点出来使用(全局性)
//生命周期:和程序同生共死,程序运行后就会一直存在内存中,知道程序结束后才会释放,因此静态成员具有唯一性
//注意:
//1.静态函数中不能直接使用非静态成员
//2.非静态函数中可以直接使用静态成员
//常量和静态变量
//常量是特殊的静态变量
//常量和静态变量相同点
//他们都可以通过类名点出来使用
//常量和静态变量不同点
//1.const必须初始化不能被修改 static没有这个规则
//2.const只能修饰变量,static可以修饰很多
//3.const不能写在访问修饰符前面 一定是写在变量申明前面 static没有这个规则
}
9.3 练习题
const和static的区别
相同点:
- 两者都可以通过类名点出来使用。
不同点:
const必须初始化不能被修改,static没有这个要求:
const
用于定义常量,其值在编译时就需要确定,并且不能在运行时修改。static
可以是变量、方法、属性等,而且其值或状态可以在运行时进行修改。
const是只能修饰变量,static可以修饰很多:
const
主要用于定义常量,修饰的是常量值。static
可以修饰变量、方法、属性等,表示这些成员是属于类而不是实例的。
访问修饰符要写在const前面,static随意:
const
必须加上访问修饰符,例如public const int MyConstant = 42;
。static
可以根据需要加上访问修饰符,也可以不加,例如private static int myStaticVariable;
。
用静态成员实现单例模式
一个类对象,在整个应用程序的生命周期中,有且仅会有一个该对象的存在,不能在外部实例化,直接通过该类类名就能够得到唯一的对象
class语句块外 namespace语句块内
// class语句块外 namespace语句块内
// 单例类
class Singleton
{
// 设置一个私有静态的对象 new出一个自己 即是唯一对象
private static Singleton instance = new Singleton();
public int singletonInt = 123;
// 使用静态属性 通过属性让外部只能得不能改
public static Singleton Instance
{
get
{
return instance;
}
}
// 写一个私有的构造函数 在外面就不能new了
private Singleton()
{
}
}
主函数内
// 主函数内
//Singleton instance = new Singleton();
//报错 构造函数私有 不能new
//要把Singleton.instance设置为private 不然有可能外部置空
//Singleton.instance = null;
//Singleton.instance设置为private后 报错
Console.WriteLine(Singleton.Instance.singletonInt);//123
9.4 练习题代码
using System;
namespace Lesson7_练习题
{
#region 练习题一
//请说出const和static的区别
//const和static的相同点
//他们都可以通过类名点出来使用
//const和static的不同点
//1.const必须初始化不能被修改,static没有这个要求
//2.const是只能修饰变量,static可以修饰很多
//3.访问修饰符要写在const前面,static随意
#endregion
#region 练习题二
//请用静态成员相关知识实现
//一个类对象,在整个应用程序的生命周期中,有且仅会有一个该对象的存在,
//不能在外部实例化,直接通过该类类名就能够得到唯一的对象
//class语句块外 namespace语句块内
//其实是单例模式的实现
// 单例 类
class Singleton
{
//设置一个私有静态的对象 new出一个自己 即是唯一对象
private static Singleton instance = new Singleton();
public int singletonInt = 123;
//使用静态属性 通过属性让外部只能得不能改
public static Singleton Instance
{
get
{
return instance;
}
}
//写一个私有的构造函数 在外面就不能new了
private Singleton()
{
}
}
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("静态成员练习题");
//主函数内
#region 练习题二
//Singleton instance = new Singleton();
//报错 构造函数私有 不能new
//要把Singleton.instance设置为private 不然有可能外部置空
//Singleton.instance = null;
//Singleton.instance设置为private后 报错
Console.WriteLine(Singleton.Instance.singletonInt);//123
#endregion
}
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com