前言
在本节课中,我们将了解面向对象编程(OOP)的核心概念:类和对象。C#是一种面向对象的编程语言,它支持封装、继承和多态特性。理解类和对象的基本概念是学习C#编程的基础。
一、类
类是最基本的C#类型。类是一种数据结构,可在一个单元中就将状态和操作结合起来。类为动态创建的类实例(也称为"对象")提供了定义。类支持继承和多形性,即派生类可以扩展和专门针对基类的机制。
1.类的声明
新类使用类声明进行创建。类声明的开头是表头,提供类的访问修饰符、类的关键字、类名以及类所继承的接口或其他基类。标头后面是类的主题,写在由分隔符{和}内编写的成员声明列表组成。
public class User
{
public string name;
public int age;
public User(string name,int age)
{
this.name = name;
this.age = age;
}
}
在上述代码中,创建了一个用户的类,其中有两个字段分别是name和age,并且包含一个构造函数。
2.类的实例化
类实例是使用new运算符进行创建,此运算符为新实例分配内存,调用构造函数来初始化实例,并返回对实例的引用。
User user1 = new User("张",18);
User user2 = new User("叶",22);
在此处将该类实例化出两个对象。当无法再访问对象时,对象占用的内存会被自欧东回收。在C#中无法显示解除分配对象。
二、成员
类成员要么是静态成员,要么是实例成员。静态成员数据类,实例成员属于对象(类实例)
类中可以包含以下成员:
常量:与类关联的常量值
字段:类的常量
方法:类可以执行的计算和操作
属性:与读取和写入类的已命名属性相关联的操作
索引器:与将类实例编入索引(像处理数据一样)相关联的操作
事件:类可以生成的通知
运算符:类支持的转换和表达式运算符
构造函数:初始化实例或类本身所需的操作
终结器:永久放弃类实例前要执行的操作
类型:类声明的嵌套类型
using System;
// 1. 定义一个名为 SampleClass 的类
public class SampleClass
{
// 常量 (Constant): 与类关联的常量值
public const double PI = 3.14159;// 字段 (Field): 类的变量
private string name;// 属性 (Property): 与读取和写入类的已命名属性相关联的操作
public string Name
{
get { return name; }
set { name = value; }
}// 索引器 (Indexer): 与将类实例编入索引相关联的操作
private string[] elements = new string[10];
public string this[int index]
{
get { return elements[index]; }
set { elements[index] = value; }
}// 事件 (Event): 类可以生成的通知
public event EventHandler NameChanged;// 运算符重载 (Operator Overloading): 类支持的运算符
public static SampleClass operator +(SampleClass a, SampleClass b)
{
return new SampleClass { Name = a.Name + " " + b.Name };
}// 构造函数 (Constructor): 初始化实例或类本身所需的操作
public SampleClass()
{
name = "Default Name";
Console.WriteLine("SampleClass Constructor called");
}// 方法 (Method): 类可以执行的计算和操作
public void DisplayInfo()
{
Console.WriteLine($"Name: {Name}");
}// 构造函数重载 (Constructor Overloading)
public SampleClass(string initialName)
{
name = initialName;
Console.WriteLine($"SampleClass Constructor with parameter called, Name set to {initialName}");
}// 终结器 (Destructor): 永久放弃类实例前要执行的操作
~SampleClass()
{
Console.WriteLine("SampleClass Destructor called");
}// 嵌套类型 (Nested Type): 类声明的嵌套类型
public class NestedClass
{
public void NestedMethod()
{
Console.WriteLine("Method inside NestedClass");
}
}// 引发事件的方法
protected virtual void OnNameChanged(EventArgs e)
{
NameChanged?.Invoke(this, e);
}// 示例方法来更改名称并引发事件
public void ChangeName(string newName)
{
if (name != newName)
{
name = newName;
OnNameChanged(EventArgs.Empty);
}
}
}class Program
{
static void Main(string[] args)
{
// 使用构造函数创建类的实例
SampleClass instance1 = new SampleClass();
SampleClass instance2 = new SampleClass("Instance 2");// 设置属性
instance1.Name = "New Name";
Console.WriteLine($"Instance1 Name: {instance1.Name}");// 使用方法
instance1.DisplayInfo();
instance2.DisplayInfo();// 使用索引器
instance1[0] = "Element 0";
Console.WriteLine($"Index 0 of instance1: {instance1[0]}");// 事件处理
instance1.NameChanged += (sender, e) => Console.WriteLine("Name has changed.");
instance1.ChangeName("Another Name");// 使用嵌套类
SampleClass.NestedClass nestedInstance = new SampleClass.NestedClass();
nestedInstance.NestedMethod();// 运算符重载的使用
SampleClass combinedInstance = instance1 + instance2;
combinedInstance.DisplayInfo(); // 程序结束时终结器被调用
}
}
三、访问修饰符(Accessibility).
每个类成员都有关联 的可访问性,用于控制能够访问的成员的程序文本区域:
public:访问不受限
protected:只能访问此类或派生自此类的类
internal:访问限于当前程序集(.exe、.dll等)
protected internal:访问受限于包含类、派生自包含类的类或同一程序集中的类
private:只能访问此类
private protected:访问限于同一程序集中的包含类或派生自包含类的类
四、类型参数Type parameters
类定义可能会按如下的方式指定一组类型参数:在类名后用尖括号扩住类型参数名称列表。然后,可以在类声明的主题中使用类型参数来定义类成员:
public class Pair<TFirst,TSecond>
{
public TFirst First;
public TSecond Second;
}
声明为使用类型参数的类类型被称为泛型类 。结构、接口或委托类型也可以是泛型。使用泛型类时,必须为每个类型参数提供类型自变量。
Pair<int,string> pair = new Pair<int,string> { First = 1, Second = "two" };
int i = pair.First; // TFirst is int
string s = pair.Second; // TSecond is string
包含类型自变量的泛型类型(如上面的 Pair<int,string>
)被称为构造泛型类型。