目录
一、C# 类
1、类的定义
2、对象的创建
3、类和对象的使用
二、C# 构造函数
1、实例构造函数
2、静态构造函数
3、私有构造函数
三、C# 析构函数
四、C# this关键字
1、表示当前类的对象
2、串联构造函数
3、作为类的索引器
4、作为原始类型的扩展方法
五、C# 静态成员
1、静态属性
2、静态函数
六、C# 结构体
1、定义结构体
2、C# 结构体的特点
3、类与结构体
在 C# 中,类是引用类型的。类由成员属性和成员方法构成。我们可以动态创建类的实例(instance),这个实例也被称为对象(object),我们可以通过类和对象来设计程序。
类的定义需要使用 class 关键字,语法格式如下:
class class_name
{
// 成员属性
variable1;
...
// 成员方法
method1(parameter_list)
{
// 函数体
}
}
语法说明如下:
类和对象是不同的概念,类决定了对象的类型,但不是对象本身。类是在开发阶段创建的,而对象则是在程序运行期间创建的。对象是基于类创建的实体,也称为类的实例。
(1)使用 new 关键字创建对象
假如我们创建了一个名为 Student 的类,若要创建这个类的对象(实例),语法格式如下:
Student Object = new Student();
前面的 Student 是我们要创建的对象类型,而 Object 则是一个变量,它引用了 Student 类实例(Student 类的对象)的内存地址。
new 关键字在这里的作用主要是在程序运行时为类的实例分配内存。
(2)使用已创建对象赋值
我们像创建普通变量那样只创建一个 Student 类型的变量,而不使用 new 关键字实例化 Student 这个类,例如:
Student Object2;
注意:这里的 Object2 只是一个 Student 类型的普通变量,它并没有被赋值,所以不能使用 Object2 来访问对象中的属性和方法。
此时,我们将一个已经创建的对象赋值给它,这时就可以使用 Object2 来访问对象中的属性和方法了。例如:
Student Object3 = new Student();
Object2 = Object3;注意:示例中的 Object2 和 Object3 指向同一个 Student 对象,因此使用 Object2 对 Student 对象的任何操作也会影响到 Object3。
我们可以通过 . 运算符来访问类中的成员,如下所示:
Student Object = new Student();
Object.variable; // 访问成员属性
Object.method(); // 访问成员方法
举例:
class Program
{
static void Main(string[] args)
{
Student s1 = new Student();
s1.insert(1, "Tom", "男", 10);
s1.display();
Student s2 = new Student();
s2.insert(2, "Jerry", "女", 5);
s2.display();
}
}
public class Student
{
public int id;
public string name;
public string sex;
public int age;
public void insert(int id, string name, string sex, int age)
{
this.id = id;
this.name = name;
this.sex = sex;
this.age = age;
}
public void display()
{
Console.WriteLine("编号:{0} 姓名:{1} 性别:{2} 年龄:{3}", id, name, sex, age);
Console.ReadKey();
}
}
在 C# 中,构造函数是与类(或结构体)具有相同名称的成员函数,不需要我们主动调用。当我们创建一个类的对象时会自动调用类中的构造函数,通常使用构造函数来初始化类中的成员属性。
C# 中的构造函数有三种:
实例构造函数是类中特殊的成员函数,它的名称与它所在类的名称相同,并且没有返回值。如下所示:
public class Person
{
private string name;
private int age;
public Person(string n, int a)
{
name = n;
age = a;
}
...
}
// 只要创建 Person 类的对象,就会调用类中的实例构造函数。
// 我们只需要在实例化对象时将具体的值传递给类中的构造函数即可,如下所示:
Person P = new Person("张三", 18);
如果没有为类显式的创建构造函数,那么 C# 将会为这个类隐式的创建一个无参构造函数,这个无参构造函数会在实例化对象时为类中的成员属性设置默认值。在结构体中也是如此,如果没有为结构体创建构造函数,那么 C# 将隐式的创建一个无参构造函数,用来将每个字段初始化为其默认值。
静态构造函数用于初始化类中的静态数据或执行仅需执行一次的特定操作。静态构造函数将在创建第一个实例或引用类中的静态成员之前自动调用。
静态构造函数具有以下特性:
举例:
实例构造函数与静态构造函数的调用时机,如下所示:
class Program
{
public static int num = 0;
// 实例构造函数
Program()
{
Console.WriteLine("实例构造函数被调用了...");
num = 1;
}
// 静态构造函数
static Program()
{
Console.WriteLine("静态构造函数被调用了...");
num = 2;
}
static void Main(string[] args)
{
Console.WriteLine("num = {0}", num);
Program p = new Program();
Console.WriteLine("num = {0}", num);
Console.ReadKey();
}
}
说明:
当执行上面程序时,会首先执行 public static int num = 0,接着执行类中的静态构造函数,
此时 num = 2,然后执行 Main 函数里面的内容,此时打印 num 的值为 2,接着初始化 Program 类,
这时会执行类中的构造函数,此时 num 会重新赋值为 1,所以上例的运行结果如下所示:
num = 2
num = 1
私有构造函数是一种特殊的实例构造函数,通常用在只包含静态成员的类中。如果一个类中具有一个或多个私有构造函数而没有公共构造函数的话,那么其他类(除嵌套类外)则无法创建该类的实例。 例如:
class Program
{
static void Main(string[] args)
{
// Student s = new Student();
Student.id = 1001;
Student.name = "Tom";
Student.Display();
Console.ReadKey();
}
}
public class Student
{
// 静态成员属性
public static int id;
public static string name;
// 私有构造函数
// 注意:如果不指定访问权限修饰符,默认为私有构造函数.
private Student() { }
// 静态成员方法
public static void Display()
{
Console.WriteLine("姓名:" + name + " ,编号:" + id);
}
}
// 上例中定义了一个空的私有构造函数,这么做的好处就是可阻止自动生成无参数构造函数.
注意:
上述代码中,如果取消 Main 函数中注释的 Student s = new Student();
程序就会出错,因为 Student 类的构造函数是私有构造函数,受其保护级别的限制不能访问。
C# 中的析构函数(也被称作"终结器")同样是类中的一个特殊成员函数,主要用于在垃圾回收器回收类实例时执行一些必要的清理操作。
C# 中的析构函数具有以下特点:
~
作为前缀;举例:
// 演示一下类中构造函数和析构函数的使用:
class Program
{
static void Main(string[] args)
{
Student s1 = new Student();
Student s2 = new Student();
Console.ReadKey();
}
}
public class Student
{
// 构造函数
public Student()
{
Console.WriteLine("构造函数被调用了...");
}
// 析构函数
~Student()
{
Console.WriteLine("析构函数被调用了...");
Console.ReadKey();
}
}
// 运行结果如下:
构造函数被调用了...
构造函数被调用了...
析构函数被调用了...
析构函数被调用了...
在 C# 中,可以使用 this 关键字来表示当前对象,访问类中的成员属性以及函数。
public Website(string n, string u){
this.name = n;
this.url = u;
}
public Test()
{
Console.WriteLine("无参构造函数");
}
// 这里的 this() 代表无参构造函数 Test()
// 先执行 Test(),后执行 Test(string text)
public Test(string text) : this()
{
Console.WriteLine(text);
Console.WriteLine("有参构造函数");
}
class Demo
{
static void Main(string[] args)
{
Test a = new Test();
Console.WriteLine("Temp0:{0}, Temp1:{1}", a[0], a[1]);
a[0] = 15;
a[1] = 20;
Console.WriteLine("Temp0:{0}, Temp1:{1}", a[0], a[1]);
}
}
public class Test
{
int Temp0;
int Temp1;
public int this[int index]
{
get
{
return (0 == index) ? Temp0 : Temp1;
}
set
{
if (0==index)
Temp0 = value;
else
Temp1 = value;
}
}
}
// 运行结果如下:
Temp0:0, Temp1:0
Temp0:15, Temp1:20
class Program
{
static void Main(string[] args)
{
string str = "百度一下";
string newStr = str.ExpandString();
Console.WriteLine(newStr);
Console.ReadKey();
}
}
public static class Test
{
public static string ExpandString(this string name)
{
return name + " https://www.baidu.com";
}
}
// 运行结果如下:
百度一下 https://www.baidu.com
在 C# 中,我们可以使用 static 关键字声明属于类型本身而不是属于特定对象的静态成员,因此不需要使用对象来访问静态成员。在类、接口和结构体中可以使用 static 关键字修饰变量、函数、构造函数、类、属性、运算符和事件。
若在定义某个成员时使用了 static 关键字,则表示该类仅存在此成员的一个实例。也就是说当我们将一个类的成员声明为静态成员时,无论创建多少个该类的对象,静态成员只会被创建一次,且会被所有对象共享。
使用 static 修饰的成员属性称为 "静态属性" 。静态属性可以直接通过类名.属性名
的形式直接访问,不需要创建类的实例。静态属性不仅可以使用成员函数来初始化,还可以直接在类外进行初始化。
举例:
class Program
{
static void Main(string[] args)
{
Test.str = "百度一下";
Console.WriteLine(Test.str);
Test test1 = new Test();
test1.GetStr();
Test test2 = new Test();
test2.GetStr();
test2.SetStr("https://www.baidu.com");
test1.GetStr();
test2.GetStr();
}
}
public class Test
{
public static string str;
public void SetStr(string s)
{
str = s;
}
public void GetStr()
{
Console.WriteLine(str);
Console.ReadKey();
}
}
// 运行结果如下:
百度一下
百度一下
百度一下
https://www.baidu.com
https://www.baidu.com
static 关键字还可以用来修饰成员函数,使用 static 修饰的成员函数称为 "静态函数" ,静态函数只能访问静态属性。
举例:
class Program
{
static void Main(string[] args)
{
Test test1 = new Test();
test1.SetStr("百度一下");
Test.GetStr();
Test test2 = new Test();
test2.SetStr("https://www.baidu.com");
Test.GetStr();
}
}
public class Test
{
public static string str;
public void SetStr(string s)
{
str = s;
}
public static void GetStr()
{
Console.WriteLine(str);
Console.ReadKey();
}
}
// 运行结果如下:
百度一下
https://www.baidu.com
在 C# 中,结构体是值类型数据结构。它使得一个单一变量可以存储各种数据类型的相关数据。
struct 关键字用于创建结构体。struct 语句为程序定义了一个带有多个成员的新的数据类型,用来代表一个记录。
struct Books
{
public string title;
public string author;
public string subject;
public int book_id;
};
在设计结构体时有以下几点需要注意:
下面的程序演示了结构体的用法:
using System;
namespace MyFirstConsoleApp
{
struct Books
{
public string title;
public string author;
public string subject;
public int book_id;
};
class Program
{
static void Main(string[] args)
{
Books Book1; /* 声明 Book1,类型为 Books */
Books Book2; /* 声明 Book2,类型为 Books */
/* book 1 详述 */
Book1.title = "C Programming";
Book1.author = "Nuha Ali";
Book1.subject = "C Programming Tutorial";
Book1.book_id = 6495407;
/* book 2 详述 */
Book2.title = "Telecom Billing";
Book2.author = "Zara Ali";
Book2.subject = "Telecom Billing Tutorial";
Book2.book_id = 6495700;
/* 打印 Book1 信息 */
Console.WriteLine("Book 1 title : {0}", Book1.title);
Console.WriteLine("Book 1 author : {0}", Book1.author);
Console.WriteLine("Book 1 subject : {0}", Book1.subject);
Console.WriteLine("Book 1 book_id :{0}", Book1.book_id);
/* 打印 Book2 信息 */
Console.WriteLine("Book 2 title : {0}", Book2.title);
Console.WriteLine("Book 2 author : {0}", Book2.author);
Console.WriteLine("Book 2 subject : {0}", Book2.subject);
Console.WriteLine("Book 2 book_id : {0}", Book2.book_id);
Console.ReadKey();
}
}
}
类和结构体的主要区别如下所示:
using System;
namespace MyFirstConsoleApp
{
struct Books
{
private string title;
private string author;
private string subject;
private int book_id;
public void SetValue(string t, string a, string s, int id)
{
title = t;
author = a;
subject = s;
book_id = id;
}
public void Display()
{
Console.WriteLine("Title:{0}", title);
Console.WriteLine("Author:{0}", author);
Console.WriteLine("Subject:{0}", subject);
Console.WriteLine("Book_id:{0}", book_id);
}
};
class Program
{
static void Main(string[] args)
{
Books book1 = new Books(); // 实例化 Books 结构体
Books book2 = new Books(); // 实例化 Books 结构体
// 定义 book1 的属性
book1.SetValue("C#教程", "Nuha Ali", "C#编程教程", 1001);
// 定义 book2 的属性
book2.SetValue("HTTP教程", "Zara Ali", "HTTP协议教程", 1002);
// 输出 book1 的属性信息
book1.Display();
// 输出 book2 的属性信息
book2.Display();
Console.ReadKey();
}
}
}