C#语言入门详解(024 025)——类的声明,继承和访问控制.mp4 (185.35MB)类声明的全貌

Class declarations.

024,025 类的声明,继承和访问控制 - 图2

C# 类声明的位置

  • 在名称空间里

    1. namespace HelloClass
    2. {
    3. class Program
    4. {
    5. ...
    6. }
    7. ...
  • 放在显式的名称空间之外
    实际上是声明在了全局名称空间里面,这是把类声明在名称空间的一种特殊情况。 ```csharp namespace HelloClass { … } class Computer {

}

  1. - 声明在类体里面(成员类)<br />成员类在学习时不常见,但实际项目中常用。
  2. ```csharp
  3. namespace HelloClass
  4. {
  5. class Program
  6. {
  7. ...
  8. class Student
  9. {
  10. ...
  11. }
  12. }
  13. }

声明即定义(C# 与 JAVA)

C++ 里面类的声明和定义默认是分开的(推荐),也可以手动写到一起。

在 C# 和 JAVA 中声明即定义。

最简单的类声明

语法:
024,025 类的声明,继承和访问控制 - 图3

即使是 ASP.NET Core 这么大的项目里面也没有特别复杂的类声明。

类成员的访问控制

class 前面没有任何修饰符等于加了 internal。

  • internal:仅在自身程序集(Assembly)里面可以访问
  • public:从 Assembly 暴露出去

:::info Code Snippet

  • F12:跳至类定义
  • Ctrl + - (减号):跳回至之前所在位置 :::

类的继承

Timothy:继承的本质是派生类在基类已有的成员基础上,对基类进行的横向和纵向的扩展。

  • 横向扩展:对类成员个数的扩充
  • 纵向扩展:对类成员(重写)版本的更新

只能扩展不能缩减,这是静态类型语言(C#、C++、JAVA 等)的特征,继承时类成员只能越来越多。
动态类型语言(Python、JavaScript)可以移除类成员。

  1. namespace HelloOOP
  2. {
  3. class Program
  4. {
  5. static void Main(string[] args)
  6. {
  7. var t = typeof(Car);
  8. var tb = t.BaseType;
  9. var top = tb.BaseType;
  10. Console.WriteLine(tb.FullName);
  11. Console.WriteLine(top.FullName);
  12. Console.WriteLine(top.BaseType == null);
  13. }
  14. }
  15. class Vehicle {}
  16. class Car : Vehicle {}
  17. }

024,025 类的声明,继承和访问控制 - 图4

is a 概念

is a:一个派生类的实例,从语义上来说也是一个基类的实例。

  1. var car = new Car();
  2. Console.WriteLine(car is Vehicle);
  3. Console.WriteLine(car is Object);
  4. var vehicle = new Vehicle();
  5. Console.WriteLine(vehicle is Car);

024,025 类的声明,继承和访问控制 - 图5

  1. // 可以用基类类型的变量来引用派生类实例
  2. Vehicle vehicle = new Car();
  3. Object o1 = new Vehicle();
  4. Object o2 = new Car();

知识点

  • sealed 封闭类,无法被继承
    024,025 类的声明,继承和访问控制 - 图6

  • C# 只支持单继承
    024,025 类的声明,继承和访问控制 - 图7

注:C++ 支持多继承,但它也受菱形继承的困扰

  • 子类的访问权限不能超越父类
    024,025 类的声明,继承和访问控制 - 图8

类成员的访问级别

类成员的访问级别以类的访问级别为上限。

命名偏好
随着越来越多 C++、JAVA 程序员加入 .NET 社区,private 字段的命名普遍遵循下划线 + 小写。
例:private int _rpm;

在团队合作中,最好的不让他人调用的方法,就直接用不用 public 修饰。
如果应该封装的成员没有封装,对方只要发现能够调用,又能解决问题,他就一定会去用,进而导致不确定的问题。

  • public
    024,025 类的声明,继承和访问控制 - 图9
  • protected internal
    024,025 类的声明,继承和访问控制 - 图10
  • internal
    024,025 类的声明,继承和访问控制 - 图11
  • protected
    024,025 类的声明,继承和访问控制 - 图12
  • private
    024,025 类的声明,继承和访问控制 - 图13

C# 7.2 推出了最新的 Private Protected: The member declared with this accessibility can be visible within the types derived from this containing type within the containing assembly. It is not visible to any types not derived from the containing type, or outside of the containing assembly. i.e., the access is limited to derived types within the containing assembly.

面向对象的实现风格

开放心态,不要有语言之争。

我们现在学到的封装、继承、多态的风格是基于类的(Class-based)
还有另外一个非常重要的风格就是基于原型的(Prototype-based),JavaScript 就是基于原型的面向对象。

Java 也是基于类的,让我们一撇 Java:
024,025 类的声明,继承和访问控制 - 图14