封装
封装有时称为面向对象的编程的第一支柱或原则。 根据封装原则,类或结构可以指定自己的每个成员对外部代码的可访问性。 可以隐藏不得在类或程序集外部使用的方法和变量,以限制编码错误或恶意攻击发生的可能性。
成员
所有方法、字段、常量、属性和事件都必须在类型中进行声明;这些被称为类型的成员。 C# 没有全局变量或方法,这一点其他某些语言不同。 即使是程序的入口点 Main 方法,也必须在类或结构中进行声明。 下面列出了所有可以在类或结构中声明的各种成员。
- 字段
- 常量
- 属性
- 方法
- 构造函数
- 事件
- 终结器
- 索引器
- 运算符
- 嵌套类型
可访问性
一些方法和属性可供类或结构外部的代码(称为“客户端代码”)调用或访问。 另一些方法和属性只能在类或结构本身中使用。
使用访问修饰符 public、protected、internal、protected internal、private 和 private protected 可指定类型及其成员对客户端代码的可访问性。 可访问性的默认值为 private。
访问修饰符是关键字,用于指定成员或类型已声明的可访问性。
可使用访问修饰符指定以下六个可访问性级别:
- public:访问不受限制。
- protected:访问限于包含类或派生自包含类的类型。
- internal:访问限于当前程序集。
- protected internal:访问限于当前程序集或派生自包含类的类型。
- private:访问限于包含类。
- private protected:访问限于包含类或当前程序集中派生自包含类的类型。
继承
继承(以及封装和多形性)是面向对象的编程的三个主要特征之一。 通过继承,可以创建重用、扩展和修改在其他类中定义的行为的新类。 其成员被继承的类称为“基类” ,继承这些成员的类称为“派生类” 。 派生类只能有一个直接基类。 但是,继承是可传递的。 如果 ClassC 派生自 ClassB,并且 ClassB 派生自 ClassA,则 ClassC 会继承在 ClassB 和 ClassA 中声明的成员。
备注:结构不支持继承,但它们可以实现接口。
从概念上讲,派生类是基类的专门化。 例如,如果有一个基类 Animal,则可以有一个名为 Mammal 的派生类,以及另一个名为 Reptile 的派生类。 Mammal 是 Animal,Reptile 也是 Animal,但每个派生类表示基类的不同专门化。
定义要从其他类派生的类时,派生类会隐式获得基类的所有成员(除了其构造函数和终结器)。 派生类因而可以重用基类中的代码,而无需重新实现。 在派生类中,可以添加更多成员。 通过这种方法,派生类可扩展基类的功能。
类(而非结构)支持继承的概念。 派生自另一个类(基类 )的类自动包含基类的所有公共、受保护和内部成员(其构造函数和终结器除外)。
可以将类声明为 abstract,即一个或多个方法没有实现代码。 尽管抽象类无法直接实例化,但可以作为提供缺少实现代码的其他类的基类。 类还可以声明为 sealed,以阻止其他类继承。
类和结构可以继承多个接口。 继承自接口意味着类型实现接口中定义的所有方法。
抽象方法和虚方法
基类将方法声明为虚拟 时,派生类可以使用其自己的实现重写该方法。 如果基类将成员声明为抽象,则必须在直接继承自该类的任何非抽象类中重写该方法。 如果派生类本身是抽象的,则它会继承抽象成员而不会实现它们。 抽象和虚拟成员是多形性(面向对象的编程的第二个主要特征)的基础。 有关详细信息,请参阅多态性。
抽象基类
如果要通过使用 new 运算符来防止直接实例化,则可以将类声明为抽象。 如果这样做,则仅当从该类派生新类时,才能使用该类。 抽象类可以包含一个或多个本身声明为抽象的方法签名。 这些签名指定参数和返回值,但没有任何实现(方法体)。 抽象类不必包含抽象成员;但是,如果类包含抽象成员,则类本身必须声明为抽象。 本身不抽象的派生类必须为来自抽象基类的任何抽象方法提供实现。 有关详细信息,请参阅抽象类、密封类和类成员。
接口
接口 是引用类型,有些类似于仅包含抽象成员的抽象基类。 类实现接口时,它必须为接口的所有成员提供实现。 类可以实现多个接口,即使它只能派生自单个直接基类。
接口用于为类定义特定功能,这些功能不一定具有“是”关系。 例如,System.IEquatable 接口可由任何类或结构实现,这些类或构造必须启用客户端代码来确定该类型的两个对象是否等效(但是由该类型定义等效性)。 IEquatable 不表示基类和派生类之间存在的同一种“是”关系(例如,Mammal 是 Animal)。
防止进一步派生
类可以通过将自己或成员声明为密封,来防止其他类继承自它或继承自其任何成员。
多态
多态性常被视为自封装和继承之后,面向对象的编程的第三个支柱。 Polymorphism(多态性)是一个希腊词,指“多种形态”,多态性具有两个截然不同的方面:
- 在运行时,在方法参数和集合或数组等位置,派生类的对象可以作为基类的对象处理。 发生此情况时,该对象的声明类型不再与运行时类型相同。
- 基类可以定义并实现虚方法,派生类可以重写这些方法,即派生类提供自己的定义和实现 。 在运行时,客户端代码调用该方法,CLR 查找对象的运行时类型,并调用虚方法的重写方法。 因此,你可以在源代码中调用基类的方法,但执行该方法的派生类版本。
在 C# 中,每个类型都是多态的,因为包括用户定义类型在内的所有类型都继承自 Object。
虚成员
当派生类从基类继承时,它会获得基类的所有方法、字段、属性和事件。 派生类的设计器可以选择是否
- 重写基类中的虚拟成员。
- 继承最接近的基类方法而不重写它
- 定义隐藏基类实现的成员的新非虚实现
仅当基类成员声明为 virtual 或 abstract 时,派生类才能重写基类成员。 派生成员必须使用 override 关键字显式指示该方法将参与虚调用。
多读多背,加油吧皮卡丘