类的介绍
在C#中,类是面向对象编程的核心概念之一。它是一种引用类型,用于封装数据和与数据相关的方法。类可以被看作是创建对象的蓝图或模板。以下是类的一些基本概念和组成部分:
-
类定义:使用关键字
class
来定义一个类。类名通常以大写字母开头。public class MyClass { // 类成员 }
-
成员变量(字段):字段是类的属性,用于存储数据。它们可以是私有的(只能在类内部访问)或公共的(可以在类的外部访问)。
public class Person { public string Name; private int age; }
-
构造函数:构造函数是一种特殊的方法,用于初始化新创建的对象。它与类同名,并且不返回任何值。
public class Car { public string Model; public string Color; public Car(string model, string color) { Model = model; Color = color; } }
-
方法:方法定义了类的行为。它们可以包含参数,并返回一个值或不返回值(即
void
)。public class Calculator { public int Add(int a, int b) { return a + b; } }
-
属性:属性提供了一种安全的访问类字段的方式。它们可以有
get
和set
块,用于读取和设置字段的值。public class Product { private double _price; public double Price { get { return _price; } set { _price = value; } } }
-
索引器:索引器允许你使用索引(如数组索引)来访问对象的属性。
public class List<T> { private T[] _items; public List(int capacity) { _items = new T[capacity]; } public T this[int index] { get { return _items[index]; } set { _items[index] = value; } } }
-
继承:类可以继承另一个类的属性和方法。被继承的类称为基类或父类,继承的类称为派生类或子类。
public class Animal { public virtual void MakeSound() { Console.WriteLine("Some sound"); } } public class Dog : Animal { public override void MakeSound() { Console.WriteLine("Bark"); } }
-
接口:接口定义了一组方法和属性,但不实现它们。类可以实现一个或多个接口。
public interface IPrintable { void Print(); } public class Document : IPrintable { public void Print() { Console.WriteLine("Printing document..."); } }
-
抽象类:抽象类是不能被实例化的类,通常包含一个或多个抽象方法。派生类必须实现这些抽象方法,除非派生类本身也是抽象的。
public abstract class Shape { public abstract double Area { get; } } public class Circle : Shape { public override double Area { get { return Math.PI * 10 * 10; } } }
-
静态成员:静态成员属于类本身,而不是类的实例。它们在所有对象之间共享。
public class MathHelper { public static double Pi = 3.14159; public static double Add(double a, double b) { return a + b; } }
类的继承
类的继承是面向对象编程(OOP)的一个核心概念,它允许我们创建基于现有类的新类,从而实现代码的重用和扩展。继承提供了一种机制,使得一个类(称为派生类或子类)可以继承另一个类(称为基类或父类)的属性和方法。
基本语法
在C#中,使用 :
符号来表示继承关系。以下是类的继承的基本语法:
public class BaseClass
{
public void BaseMethod()
{
Console.WriteLine("Method in Base Class");
}
}
public class DerivedClass : BaseClass
{
public void DerivedMethod()
{
Console.WriteLine("Method in Derived Class");
}
}
在这个例子中,DerivedClass
继承了 BaseClass
。因此,DerivedClass
的对象可以访问 BaseClass
中定义的方法和属性。
访问修饰符
-
public:公有成员可以在任何地方被访问。
-
protected:受保护成员只能在类本身或派生类中被访问。
-
private:私有成员只能在类本身内部被访问。
覆盖方法
派生类可以覆盖基类中的方法,这在C#中称为方法重写。为了重写方法,你需要在基类中使用 virtual
关键字声明方法,并在派生类中使用 override
关键字来实现它:
public class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("Some sound");
}
}
public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("Bark");
}
}
在这个例子中,Dog
类重写了 Animal
类中的 MakeSound
方法。
抽象类和方法
抽象类是一种不能被实例化的类,它通常包含一个或多个抽象方法。抽象方法是没有实现体的方法,派生类必须实现这些方法,除非派生类本身也是抽象的:
public abstract class Shape
{
public abstract double Area { get; }
}
public class Circle : Shape
{
public override double Area
{
get { return Math.PI * 10 * 10; }
}
}
在这个例子中,Shape
是一个抽象类,它定义了一个抽象属性 Area
。Circle
类继承了 Shape
并实现了 Area
属性。
构造函数
当创建派生类的实例时,基类的构造函数也会被调用。如果基类有一个无参数的构造函数,它将首先被调用,然后是派生类的构造函数。如果基类没有无参数的构造函数,派生类必须显式调用基类的构造函数:
public class BaseClass
{
public BaseClass()
{
Console.WriteLine("Base class constructor");
}
}
public class DerivedClass : BaseClass
{
public DerivedClass() : base()
{
Console.WriteLine("Derived class constructor");
}
}
在这个例子中,DerivedClass
通过 : base()
显式调用了 BaseClass
的构造函数。
类加载的顺序
在C#中,类加载的顺序涉及到几个关键的步骤,这些步骤包括编译时的静态成员初始化和运行时的对象实例化。以下是类加载过程中的主要阶段:
-
编译时静态成员初始化:
-
在编译时,静态字段会被初始化为默认值。
-
然后,静态构造函数(如果有的话)会被执行,用于初始化静态字段。
-
-
运行时对象实例化:
-
当创建类的实例时,首先会调用基类的静态构造函数(如果有的话)。
-
接着,基类的实例构造函数会被调用。
-
然后,派生类的静态构造函数(如果有的话)会被调用。
-
最后,派生类的实例构造函数会被调用。
-
这个过程可以用以下示例来说明:
public class BaseClass
{
static BaseClass()
{
Console.WriteLine("BaseClass static constructor");
}
public BaseClass()
{
Console.WriteLine("BaseClass instance constructor");
}
}
public class DerivedClass : BaseClass
{
static DerivedClass()
{
Console.WriteLine("DerivedClass static constructor");
}
public DerivedClass()
{
Console.WriteLine("DerivedClass instance constructor");
}
}
class Program
{
static void Main(string[] args)
{
DerivedClass derived = new DerivedClass();
}
}
当运行上述程序时,控制台输出将会是:
BaseClass static constructor
DerivedClass static constructor
BaseClass instance constructor
DerivedClass instance constructor
这个顺序说明了类加载和初始化的顺序:
-
基类的静态构造函数:首先执行基类的静态构造函数。
-
派生类的静态构造函数:然后执行派生类的静态构造函数。
-
基类的实例构造函数:接着执行基类的实例构造函数。
-
派生类的实例构造函数:最后执行派生类的实例构造函数。
注意事项
-
静态成员初始化:静态成员在类第一次被引用时初始化,而不是在第一次创建对象时。
-
静态构造函数:静态构造函数在类第一次被引用时执行,用于初始化静态成员。
-
实例构造函数:实例构造函数在创建对象时执行,用于初始化实例成员。
这个加载和初始化顺序确保了在创建对象之前,所有的静态成员和基类的成员都已经正确初始化。