类(C# 编程指南)Classes (C# Programming Guide)

引用类型Reference types

定义为的一个类型是引用类型A type that is defined as a class is a reference type. 在运行时,如果声明引用类型的变量,此变量就会一直包含值 null,直到使用 new 运算符显式创建类实例,或直到为此变量分配可能已在其他位置创建的兼容类型的对象,如下面的示例所示:At run time, when you declare a variable of a reference type, the variable contains the value null until you explicitly create an instance of the class by using the new operator, or assign it an object of a compatible type that may have been created elsewhere, as shown in the following example:

//Declaring an object of type MyClass.
MyClass mc = new MyClass();

//Declaring another object of the same type, assigning it the value of the first object.
MyClass mc2 = mc;

创建对象时,在该托管堆上为该特定对象分足够的内存,并且该变量仅保存对所述对象位置的引用。When the object is created, enough memory is allocated on the managed heap for that specific object, and the variable holds only a reference to the location of said object. 当分配托管堆上的类型和由 CLR 的自动内存管理功能对其进行回收(称为垃圾回收)时,需要开销。Types on the managed heap require overhead both when they are allocated and when they are reclaimed by the automatic memory management functionality of the CLR, which is known as garbage collection. 但是,垃圾回收已是高度优化,并且在大多数情况下,不会产生性能问题。However, garbage collection is also highly optimized and in most scenarios, it does not create a performance issue. 有关垃圾回收的详细信息,请参阅自动内存管理和垃圾回收For more information about garbage collection, see Automatic memory management and garbage collection.

声明类Declaring Classes

使用后跟唯一标识符的 class 关键字可以声明类,如下例所示:Classes are declared by using the class keyword followed by a unique identifier, as shown in the following example:

//[access modifier] - [class] - [identifier]
public class Customer
{
   // Fields, properties, methods and events go here...
}

class 关键字前面是访问级别。The class keyword is preceded by the access level. 因为此例中使用的是 public,所以任何人都可以创建此类的实例。Because public is used in this case, anyone can create instances of this class. 类的名称遵循 class 关键字。The name of the class follows the class keyword. 类名称必须是有效的 C# 标识符名称The name of the class must be a valid C# identifier name. 定义的其余部分是类的主体,其中定义了行为和数据。The remainder of the definition is the class body, where the behavior and data are defined. 类上的字段、属性、方法和事件统称为类成员Fields, properties, methods, and events on a class are collectively referred to as class members.

创建对象Creating objects

虽然它们有时可以互换使用,但类和对象是不同的概念。Although they are sometimes used interchangeably, a class and an object are different things. 类定义对象类型,但不是对象本身。A class defines a type of object, but it is not an object itself. 对象是基于类的具体实体,有时称为类的实例。An object is a concrete entity based on a class, and is sometimes referred to as an instance of a class.

可通过使用 new 关键字,后跟对象要基于的类的名称,来创建对象,如:Objects can be created by using the new keyword followed by the name of the class that the object will be based on, like this:

Customer object1 = new Customer();

创建类的实例后,会将一个该对象的引用传递回程序员。When an instance of a class is created, a reference to the object is passed back to the programmer. 在上一示例中,object1 是对基于 Customer 的对象的引用。In the previous example, object1 is a reference to an object that is based on Customer. 该引用指向新对象,但不包含对象数据本身。This reference refers to the new object but does not contain the object data itself. 事实上,可以创建对象引用,而完全无需创建对象本身:In fact, you can create an object reference without creating an object at all:

 Customer object2;

不建议创建这样一个不引用对象的对象引用,因为尝试通过这类引用访问对象会在运行时失败。We don't recommend creating object references such as this one that don't refer to an object because trying to access an object through such a reference will fail at run time. 但实际上可以使用这类引用来引用某个对象,方法是创建新对象,或者将其分配给现有对象,例如:However, such a reference can be made to refer to an object, either by creating a new object, or by assigning it to an existing object, such as this:

Customer object3 = new Customer();
Customer object4 = object3;

此代码创建指向同一对象的两个对象引用。This code creates two object references that both refer to the same object. 因此,通过 object3 对对象做出的任何更改都会在后续使用 object4 时反映出来。Therefore, any changes to the object made through object3 are reflected in subsequent uses of object4. 由于基于类的对象是通过引用来实现其引用的,因此类被称为引用类型。Because objects that are based on classes are referred to by reference, classes are known as reference types.

类继承Class inheritance

类完全支持继承,这是面向对象的编程的基本特点。Classes fully support inheritance, a fundamental characteristic of object-oriented programming. 创建类时,可以继承自其他任何未定义为 sealed 的接口或类,而且其他类也可以继承自你的类并重写类虚方法。When you create a class, you can inherit from any other interface or class that is not defined as sealed, and other classes can inherit from your class and override class virtual methods.

继承是通过使用派生来完成的,这意味着类是通过使用其数据和行为所派生自的基类来声明的。Inheritance is accomplished by using a derivation, which means a class is declared by using a base class from which it inherits data and behavior. 基类通过在派生的类名称后面追加冒号和基类名称来指定,如:A base class is specified by appending a colon and the name of the base class following the derived class name, like this:

public class Manager : Employee
{
    // Employee fields, properties, methods and events are inherited
    // New Manager fields, properties, methods and events go here...
}

类声明基类时,会继承基类除构造函数外的所有成员。When a class declares a base class, it inherits all the members of the base class except the constructors. 有关详细信息,请参阅继承For more information, see Inheritance.

与 C++ 不同,C# 中的类只能直接从基类继承。Unlike C++, a class in C# can only directly inherit from one base class. 但是,因为基类本身可能继承自其他类,因此类可能间接继承多个基类。However, because a base class may itself inherit from another class, a class may indirectly inherit multiple base classes. 此外,类还可以直接实现多个接口。Furthermore, a class can directly implement more than one interface. 有关详细信息,请参阅接口For more information, see Interfaces.

类可以声明为 abstract(抽象)。A class can be declared abstract. 抽象类包含抽象方法,抽象方法包含签名定义但不包含实现。An abstract class contains abstract methods that have a signature definition but no implementation. 抽象类不能实例化。Abstract classes cannot be instantiated. 只能通过可实现抽象方法的派生类来使用该类。They can only be used through derived classes that implement the abstract methods. 与此相反,sealed(密封)类不允许其他类继承。By contrast, a sealed class does not allow other classes to derive from it. 有关详细信息,请参阅抽象类、密封类和类成员For more information, see Abstract and Sealed Classes and Class Members.

类定义可以在不同的源文件之间分割。Class definitions can be split between different source files. 有关详细信息,请参阅分部类和方法For more information, see Partial Classes and Methods.

示例Example

以下示例定义了一个公共类,该类包含一个自动实现的属性、一个方法和一个名为构造函数的特殊方法。The following example defines a public class that contains an auto-implemented property, a method, and a special method called a constructor. 有关详细信息,请参阅属性方法构造函数主题。For more information, see Properties, Methods, and Constructors topics. 然后使用 new 关键字实例化类的实例。The instances of the class are then instantiated with the new keyword.

using System;

public class Person
{
    // Constructor that takes no arguments:
    public Person()
    {
        Name = "unknown";
    }

    // Constructor that takes one argument:
    public Person(string name)
    {
        Name = name;
    }

    // Auto-implemented readonly property:
    public string Name { get; }

    // Method that overrides the base class (System.Object) implementation.
    public override string ToString()
    {
        return Name;
    }
}
class TestPerson
{
    static void Main()
    {
        // Call the constructor that has no parameters.
        var person1 = new Person();
        Console.WriteLine(person1.Name);

        // Call the constructor that has one parameter.
        var person2 = new Person("Sarah Jones");
        Console.WriteLine(person2.Name);
        // Get the string representation of the person2 instance.
        Console.WriteLine(person2);

        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
// Output:
// unknown
// Sarah Jones
// Sarah Jones

C# 语言规范C# Language Specification

有关详细信息,请参阅 C# 语言规范For more information, see the C# Language Specification. 该语言规范是 C# 语法和用法的权威资料。The language specification is the definitive source for C# syntax and usage.

请参阅See also