02010702 深入理解类02-构造函数

02010702 深入理解类02-构造函数

1. 实例构造函数

  • 构造函数是一个特殊的方法,他在创建类的每个实例时进行。
    • 构造函数用于初始化类实例的状态。
    • 如果希望从类的外部创建类的实例,需要将构造函数声明为public。
    • 构造函数的名称和类名相同。
    • 构造函数不能有返回值。
// 构造函数声明
class MyClass
{
    public MyClass
    {
        ...
    }
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 构造函数初始化字段
class MyClass
{
    DateTime TimeOfNow; // 声明字段
    public MyClass
    {
        TimeOfNow = Datetime.Now; // 初始化字段
    }
}

说明:
1. Datetime类是从BLC(基类库)引入的,Now是DateTime的静态属性。
2. Now属性创建了一个新的DateTime实例,返回新DateTime实例的引用,赋值给MyClass类的TimeOfNow字段。

2. 带参数的构造函数

  • 构造函数在下列方面与其他方法类似。
    • 构造函数可以带参数,参数的语法与其它方法完全相同。
    • 构造函数可以被重载。
  • 在使用对象创建表达式创建类的实例时,要使用new运算符,后面跟着类的某个构造函数,new运算符使用该构造函数创建类的实例。
class MyClass
{
    int Id;
    string Name;
    
    public MyClass(){} // 无参构造函数
    public MyClass(int var){Id = val; Name="Qinway"}; // 带一个参数的构造函数
    public MyClass(int var, string name){Id = val, Name=name}; // 带两个参数的构造函数
}

public staitc void Main()
{
	MyClass myClass01 = new MyClass(); // 调用无参的构造函数创建对象,对象字段都是默认值。
    MyClass myClass02 = new MyClass(10); // 调用带一个参数的构造函数创建对象,对象字段Id为10,Name为Qinway。
    MyClass myClass03 = new MyClass(20, "Qinway"); // 调用带两个参数的构造函数创建对象,对象字段Id为20,Name为Qinway。
}

3. 默认构造函数

  • 如果在类的声明中没有显示的声明构造函数,那么编译器会提供一个隐式的默认构造函数,它有如下特征。

    • 没有参数
    • 方法体为空
  • 注意:如果为类声明了任何构造函数,那么编译器将不会为该类定义默认构造函数。

4. 静态构造函数

4.1 静态构造函数的作用
  • 构造函数也可以声明为static。
    • 实例构造函数初始化类的每个新实例
    • static修饰的构造函数初始化类级别的项。通常,静态构造函数初始化类的静态字段。
  • 初始化类级别的项。
    • 在引用任何静态成员之前。
    • 在创建类的任何实例之前。
4.2 静态构造函数与实例构造函数的异同
  • 相同处
    • 静态构造函数的名称必须和类名相同。
    • 构造函数不能有返回值。
  • 不同处
    • 静态构造函数声明中使用static关键字。
    • 类只能有一个静态函数,而且不能带参数。
    • 静态构造函数不能有访问修饰符(即默认为private)。
4.3 关于静态构造函数的注意事项
  • 类既可以有静态构造函数,也可以有实例构造函数。
  • 如同静态方法,静态构造函数不能访问所在类的实例成员,因此不能使用this访问器。
  • 不能从程序显示的调用静态函数,系统会自动调用静态函数。
    • 系统会在类的任何实例被创建之前调用静态构造函数。
    • 系统会在类的任何静态成员被引用之前调用静态构造函数。
4.4 静态构造函数示例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Demo01
{
    class MyClass
    {
        private static Random RandomKey;
        static MyClass()
        {
            RandomKey = new Random();
        }  

        public int GetRandomNumber()
        {
            return RandomKey.Next();
        }
    }
class Program
    {
        static void Main()
        {
            MyClass mc01 = new MyClass();
            MyClass mc02 = new MyClass();
            Console.WriteLine($"Next Random:{mc01.GetRandomNumber()}");
            Console.WriteLine($"Next Random:{mc02.GetRandomNumber()}");

            Console.ReadLine();
        }
    }
}

控制台输出:
Next Random:837852080
Next Random:582353176

5. 对象初始化语句

  • 对象初始化语句 → 由关键字new后面跟一个类构造函数及其参数列表组成。
// 对象初始化语句形式1:包括构造函数的参数列表
new MyClass(10, 20);
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 对象初始化语句形式2:不包括参数列表,甚至不适用括起来参数列表的圆括号
new MyClass;
  • 对象初始化语句的注意事项。
    • 创建对象的代码必须能够访问要初始化的字段和属性,即这些属性要必须是公有的。
    • 初始化发生在构造方法执行之后,因此在构造方法中设置的值可能会在之后对象初始化中重置为不同的值。

6. readonly修饰符

  • 字段可以用readonly修饰符声明。其作用于类似于将字段声明为const,一旦值被设定就不能改变。
  • const字段只能在声明语句中初始化,而readonly字段可以在如下任意位置设置它的值。
    • 字段声明语句,类似于const。
    • 类的任何构造函数。如果是static字段,初始化必须在静态构造函数中声明。
  • const字段的值必须在编译时决定,而readonly字段的值可以在运行时决定,这种自由性允许你在不同的环境或不同的构造函数中设置不同的值。
  • const的行为总是静态的,而对于readonly字段有如下特点。
    • 它可以是实例字段,也可以是静态字段。
    • 它在内存中有位置。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Demo01
{
    class MyClass
    {
        public readonly double PI = 3.14; // 初始化字段
        public readonly int MyInt; // 未初始化字段

        public MyClass(int Val01)
        {
            MyInt = 10; // 在构造函数中设定
        }

        public MyClass(double Val01, int Val02)
        {
            MyInt = Val02; // 在构造函数中设定
        }
    }
    class Program
    {
        static void Main()
        {
            MyClass mc01 = new MyClass(1);
            MyClass mc02 = new MyClass(2, 3);
            Console.WriteLine($"Next Random:PI={mc01.PI},MyInt={mc01.MyInt}");
            Console.WriteLine($"Next Random:PI={mc02.PI},MyInt={mc02.MyInt}");

            Console.ReadLine();
        }
    }
}

控制台输出:
Next Random:PI=3.14,MyInt=10
Next Random:PI=3.14,MyInt=3

结尾

书籍:C#图解教程

著:【美】丹尼尔 · 索利斯;卡尔 · 施罗坦博尔

译:窦衍森;姚琪琳

ISBN:978-7-115-51918-4

版次:第5版

发行:人民邮电出版社

※敬请购买正版书籍,侵删请联系85863947@qq.com※

※本文章为看书或查阅资料而总结的笔记,仅供参考,如有错误请留言指正,谢谢!※

posted @ 2025-08-10 22:09  qinway  阅读(8)  评论(0)    收藏  举报