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

这篇具有很好参考价值的文章主要介绍了第十单元 面向对象二:静态类与静态成员。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

我们天天都在使用

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 类中, 声明一个静态方法,并输出静态成员变量。

  

视频教程:

C#入门到精通 - 网易云课堂 (163.com)文章来源地址https://www.toymoban.com/news/detail-464463.html

到了这里,关于第十单元 面向对象二:静态类与静态成员的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++系列P5】‘类与对象‘-三部曲——[对象&特殊成员](3/3)

     前言 大家好吖,欢迎来到 YY 滴 C++系列 ,热烈欢迎! 【 \\\'类与对象\\\'-三部曲】的大纲主要内容如下 : 如标题所示,本章是【 \\\'类与对象\\\'-三部曲】三章中的第三章节——对象成员章节,主要内容如下: 目录 一.const成员/成员函数 一.用const修饰this指针的好处——含权限知识点

    2024年02月06日
    浏览(32)
  • [C++] 类与对象(中)类中六个默认成员函数(1)

      目录 1、类的六个默认成员函数 2、构造函数 2.1 构造函数的概念 2.2 特性 2.2.1 构造函数的重载: 2.2.2 全缺省的构造函数: 3、析构函数 3.1 析构函数的概念 3.2 特性 4、拷贝构造函数 4.1 拷贝构造函数的概念 4.2 特征 如果一个类中什么成员都没有,简称为空类。空类中真的什

    2024年02月12日
    浏览(29)
  • 【C++】类与对象(2补充运算符重载,const成员)

    作者:爱写代码的刚子 时间:2023.5.11 本篇作为【C++】类与对象(2)的补充(运算符重载、const成员) 赋值运算符重载 运算符重载 C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类 型,函数名字以及参数列表,其返回值类

    2024年02月04日
    浏览(27)
  • Java面向对象01——类与对象

    大家好,我是白夜,今天和大家聊聊类与对象 面向过程编程 C 语言就是面向过程编程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。 面向对象编程 JAVA 是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。 举

    2024年04月08日
    浏览(33)
  • C++初阶--类与对象--const成员和日期类的实现

    将const修饰的成员函数称之为const成员函数。 在一个成员函数里面,对于this指针指向的对象,是隐藏式的,没有办法用常规的方法去修饰它,所以我们是这样进行修饰的: 注意事项: date.h date.cpp 这里采用多文件编程的方式,所以在date.cpp中,是在Date类外使用的,需要加上作

    2024年02月05日
    浏览(27)
  • TypeScript类与对象:面向对象编程的基础

    TypeScript 是 JavaScript 的一个超集,它为 JavaScript 添加了静态类型、类、接口和装饰器等面向对象编程的特性,并通过编译器将 TypeScript 编译成JavaScript,可以在任何 JavaScript 环境中运行,因此成为了 JavaScript 开发中不可或缺的工具。面向对象编程是现代编程语言的基础,而 Ty

    2024年02月09日
    浏览(29)
  • C++ 之 【类与对象】从入门到精通一条龙服务 最终篇(static成员、友元、匿名对象。。。)

    💴到用时方恨早,白首方悔挣的少 车到山前没有路,悬崖勒马勒不住 –❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀-正文开始-❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀– 在创建对象时,编译器通过调用构造函数,给对象中各个

    2024年04月16日
    浏览(34)
  • Python 面向对象(一)(成员方法、类和对象)

    学校开学,要求学生填写自己的基础信息,一人发一张白纸,让学生自己填 改为登记表,打印出来让学生自行填写: 在程序中简单使用变量来记录学生信息  使用变量记录数据太乱了。 如果程序中也和生活中一样 可以设计表格 可以将设计的表格打印出来 可以将打印好的表

    2024年02月15日
    浏览(32)
  • 【是C++,不是C艹】 类与对象 | 默认成员函数 | 构造函数 | 析构函数

    💞💞 欢迎来到 Claffic 的博客 💞💞  👉  专栏: 《是C++,不是C艹》👈 前言: 在完成类与对象的认识后,我们接着学习类与对象的第二部分:默认成员函数,它包括构造函数,析构函数,拷贝构造,赋值重载,普通对象取地址和const对象取地址重载,放心,这一期不会都

    2024年02月09日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包