首页 > 其他分享 >第十单元 面向对象二:静态类与静态成员

第十单元 面向对象二:静态类与静态成员

时间:2023-05-30 13:45:09浏览次数:46  
标签:第十 静态 成员 面向对象 实例 static public 构造函数

前言

我们天天都在使用

Console.WriteLine("Hello world");
​
Console.ReadLine("");
​
Arrays.Sort()

  

为什么Console 类 调用 方法不需要实例化而可以直接调用呢?

我们可以查看Console的源码发现Console类定义如下:

public static class Console
{
    // ... 
}

  

我们发现 Console 类 前面有个 static 关键字修饰, 我们把 static 修饰的类 叫作 静态类

1. 静态类

static关键字的作用

  • static是静态的意思,可以修饰成员变量和成员方法。

  • static修饰成员变量表示该成员变量只在内存中只存储一份,可以被共享访问、修改。

public static class MyConsole 
{
    // 静态构造方法
    static MyConsole()
    {

    }
    // 静态变量
    public static string Title { get; set; }

    public static string Description {  get; set; }
    // 静态方法
    public static void WriteLine(params string[] s)
    {

    }
}

class Program
{
    static void Main(string[] args)
    {
        MyConsole.Title = "Hello,静态类";
        MyConsole.WriteLine("静态方法调用");
    }
}

 

静态类基本上与非静态类相同,但存在一个差异:静态类无法实例化。 换句话说,无法使用 new 运算符创建类类型的变量。 由于不存在任何实例变量,因此可以使用类名本身访问静态类的成员

与所有类类型的情况一样,加载引用该类的程序时,.NET 运行时会加载静态类的类型信息。 程序无法确切指定类加载的时间。 但是,可保证进行加载,以及在程序中首次引用类之前初始化其字段并调用其静态构造函数。 静态构造函数只调用一次,在程序所驻留的应用程序域的生存期内,静态类会保留在内存中。

 

以下列表提供静态类的主要功能:

  • 只包含静态成员。

  • 无法进行实例化。

  • 会进行密封。

  • 不能包含实例构造函数

因此,创建静态类基本上与创建只包含静态成员和私有构造函数的类相同。 私有构造函数可防止类进行实例化。 使用静态类的优点是编译器可以进行检查,以确保不会意外地添加任何实例成员。 编译器可保证无法创建此类的实例。

静态类会进行密封,因此不能继承。 它们不能继承自任何类(除了 Object)。 静态类不能包含实例构造函数。 但是,它们可以包含静态构造函数。 如果非静态类包含了需要进行有意义的初始化的静态成员,则它也应该定义一个静态构造器。

2. 非静态类的静态成员

非静态类

不被static 关键字修饰的类称为非静态类.

 

非静态类可以包含静态方法、字段、属性或事件。 即使未创建类的任何实例,也可对类调用静态成员。 静态成员始终按类名(而不是实例名称)进行访问。 静态成员只有一个副本存在(与创建的类的实例数无关)。 静态方法和属性无法在其包含类型中访问非静态字段和事件,它们无法访问任何对象的实例变量,除非在方法参数中显式传递它。

更典型的做法是声明具有一些静态成员的非静态类(而不是将整个类都声明为静态)。 静态字段的两个常见用途是保留已实例化的对象数的计数,或是存储必须在所有实例间共享的值。

静态方法可以进行重载,但不能进行替代,因为它们属于类,而不属于类的任何实例。

虽然字段不能声明为 static const,不过 static const 字段在其行为方面本质上是静态的。 它属于类型,而不属于类型的实例。 因此,可以使用用于静态字段的相同 ClassName.MemberName 表示法来访问 const 字段。 无需进行对象实例化。

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

可在成员的返回类型之前使用 static 关键字声明静态类成员,如下面的示例所示:

public class Cat // 非静态类
{
    public string Name { get; set; } // 实例变量,属于对象
    public static int Leg { get; set; } // 静态成员变量,, 属于类

    // 重载静态方法run, 属于类
    public static void Run()
    {
        // Console.WriteLine(this.Name);// 报错,静态方法中,不能访问实例成员
        Console.WriteLine($"{Leg} 条腿的猫在跑步");// 正确,静态类中可以访问静态成员变量
    }
    // 重载静态方法run, 属于类
    public static void Run(int speed)
    {
        Console.WriteLine($"{Leg} 条腿的猫在跑步,速度是:{speed}");
    }
    
    // 实例方法,属于对象
    public void Eat()
    {
        // 实例方法既可以访问成员变量,也可以访问静态变量
        Console.WriteLine($"{Leg} 条腿的 {this.Name} 在抢狗粮吃。") ; 
    }
}

 

在首次访问静态成员之前以及在调用构造函数(如果有)之前,会初始化静态成员。 若要访问静态类成员,请使用类的名称(而不是变量名称)指定成员的位置,如下面的示例所示:

static void Main(string[] args)
{
    Cat.Leg = 4;
    Cat.Run(30);
    
    Cat c = new Cat();
    c.Eat();
}

 

3. 静态构造方法

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

class SimpleClass
{
    // Static variable that must be initialized at run time.
    static readonly long baseline;

    // Static constructor is called at most one time, before any
    // instance constructor is invoked or member is accessed.
    static SimpleClass()
    {
        baseline = DateTime.Now.Ticks;
    }
}

 

静态构造函数具有以下属性:

  • 静态构造函数不使用访问修饰符或不具有参数。

  • 类或结构只能有一个静态构造函数。

  • 静态构造函数不能继承或重载。

  • 静态构造函数不能直接调用,并且仅应由公共语言运行时 (CLR) 调用。 可以自动调用它们。

  • 用户无法控制在程序中执行静态构造函数的时间。

  • 自动调用静态构造函数。 它在创建第一个实例或引用该类(不是其基类)中声明的任何静态成员之前初始化。 静态构造函数在实例构造函数之前运行。 调用(而不是分配)分配给事件或委托的静态方法时,将调用类型的静态构造函数。 如果静态构造函数类中存在静态字段变量初始值设定项,它们将以在类声明中显示的文本顺序执行。 初始值设定项紧接着执行静态构造函数之前运行。

  • 如果未提供静态构造函数来初始化静态字段,会将所有静态字段初始化为其默认值,如 C# 类型的默认值中所列。

  • 如果静态构造函数引发异常,运行时将不会再次调用该函数,并且类型在应用程序域的生存期内将保持未初始化。 大多数情况下,当静态构造函数无法实例化一个类型时,或者当静态构造函数中发生未经处理的异常时,将引发 TypeInitializationException 异常。 对于未在源代码中显式定义的静态构造函数,故障排除可能需要检查中间语言 (IL) 代码。

  • 静态构造函数的存在将防止添加 BeforeFieldInit 类型属性。 这将限制运行时优化。

  • 声明为 static readonly 的字段可能仅被分配为其声明的一部分或在静态构造函数中。 如果不需要显式静态构造函数,请在声明时初始化静态字段,而不是通过静态构造函数,以实现更好的运行时优化。

  • 运行时在单个应用程序域中多次调用静态构造函数。 该调用是基于特定类型的类在锁定区域中进行的。 静态构造函数的主体中不需要其他锁定机制。 若要避免死锁的风险,请勿阻止静态构造函数和初始值设定项中的当前线程。 例如,不要等待任务、线程、等待句柄或事件,不要获取锁定,也不要执行阻止并行操作,如并行循环、Parallel.Invoke 和并行 LINQ 查询。

单例模式实现

class MyDbContext
{
    private static MyDbContext _instance;
    // 禁止外部实例化
    private MyDbContext()
    {

    }

    public static string DbName;
    public static string UserName;
    public static string Password;
    
    // 静态构造方法
    static MyDbContext()
    {
        DbName = "SqlServer";
        UserName = "sa";
        Password = "123456";
        // 实例化一次
        _instance = new MyDbContext();
    }
    // 对外提供访问的路径
    public MyDbContext Instance
    {
        get { return _instance; }
    }

    public void Connection()
    {

    }

    public void Abort()
    {

    }
}

 

4. 作业

  1. 定义一个静态类 MyMath

  2. MyMath类中 实现两个参数的方法:加,减,乘,除,平均数

  3. 重载 :加,减,乘,除,平均数

  4. 定义一个非静态类 CommonUtils, 任意声明两个实例成员变量与静态成员变量

  5. CommonUtils类中,声明一个实例方法,并输出 上述的实例成员变量与静态成员变量。

  6. CommonUtils 类中, 声明一个静态方法,并输出静态成员变量。

  

视频教程:

誉尚学教育_誉尚学教育腾讯课堂官网 (qq.com)
或者:
C# 最强入门编程(.Net 学习系列开山巨作)_哔哩哔哩_bilibili

标签:第十,静态,成员,面向对象,实例,static,public,构造函数
From: https://www.cnblogs.com/xuyubing/p/17442995.html

相关文章

  • 第九单元 面向对象一:类与对象
    假设,班级里40位同学,我们用程序保存40位学生的信息:学号,姓名,性别,生日,身份证号。如果是你,你会怎么实现?小菜同学拿到这个题,奋书疾笔,马上写出如下代码:ArrayListlist=newArrayList();​stringstuNo1="10001";stringname1="张三";stringsex="男";Datetimebirthday1=D......
  • tailwindcss在使用cdn引入静态html的时候,使用vscode代码提示
    原文:Hey!TheIntellisenseextensiondoesneedaconfigfiletoworktoday.Iwouldsuggestcreatingoneinyourprojectroottoenabletheextension.Anemptyfilewillworkjustfineforthiscaseifthedefaultssuityourneeds.Ifyouwanttocustomiz......
  • 静态内部类,局部内部类
        ......
  • 第十二届蓝桥杯c++b组国赛题解(还在持续更新中...)
    试题A:带宽解题思路:由于小蓝家的网络带宽是200Mbps,即200Mb/s,所以一秒钟可以下载200Mb的内容,根据1B=8b的换算规则,所以200Mb=200/8MB=25MB。所以小蓝家的网络理论上每秒钟最多可以从网上下载25MB的内容。代码实现:#include<iostream>#include<algorithm>usingnamespacestd......
  • 在linux上搭建web服务(静态网站)
    目录在linux上搭建web服务(静态网站)一、简介1.1.什么是web服务器1.2.web服务器的工作原理1.3.web服务软件有哪些1.4.http/https协议1.5.URL/URI1.6.apache1.7.nginx二、搭建apache服务,部署静态网站1.1.安装apache服务程序1.2.配置服务器文件参数1.2.1.配置文件/etc/httpd/conf/ht......
  • SWE学习-第十八节
    端子排编辑插入端子排 右击 端子排编辑 插入十个端子 端子设备选型CTRL+A全选分配端子型号 选择端子型号,添加 添加完成  桥接端子选择端子-然后高级-跳线端子序号不对时,需要重新排列时CTRL+A全选点击重新排列---选择端子标注,不用原理图上位置......
  • SWE学习-第十七节
     电缆关联关联电缆芯 选择需要的电缆 关联被选择的电缆-选择好了点击关联电缆芯 成品图 ......
  • 考古笔记7:静态路由与联网(完整实验过程+爬坑记录)
    先上结论汇总配置过程:(无坑结论)爬坑历程拓扑配置R1:SW:PC侧验证问题1重启下交换机sw1;未解决,尝试端口重启;未解决尝试给SW1的vlan10和vlan20分配物理端口尝试f0/14连接一个host主机试试;连接的host不需要配置IP地址;重启SW1(似乎host开不开机都无所谓)删除f0/14和f0/15的Host;重启SW1解答看......
  • 面向对象设计领域中的参数多态,包含多态,过载多态和强制多态
    参数多态参数多态是指在面向对象编程中,方法的参数可以接受不同类型的对象,并根据实际传递的对象类型来执行不同的操作。它是多态的一种应用形式,通过参数的多态性,可以实现灵活的代码设计和重用。使用场景:当方法需要操作的对象类型不确定时,可以使用多态来接受不同类型的对象,减少......
  • SWE学习-第十五节
     动态插入PLC --确定选择已有的PLC  ......