P25、26 类的声明、访问级别、继承、成员访问控制

1 类声明的全貌

1.1 C#类声明的位置

  • 类声明在名称空间里
namespace HelloClass
{
    class Program
    {

    }
}
  • 类声明在显式的名称空间之外

    实际上是声明在了全局名称空间里面,这是把类声明在名称空间的一种特殊情况。平时写软件项目中没人会这么写,也不推荐这么写

namespace HelloClass
{
}

class Program
{

}
  • 声明在类体里面(成员类)

    成员类在学习时不常见,但实际项目中很常用

namespace HelloClass
{
    class Program
    {
        static void Main(string[] args)
        {

        }

        class Student//成员类
        {

        }
    }
}

1.2 声明即定义(C#与Java)

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

在 C# 和 Java 中声明即定义,两者不分开。

2 最简单的类声明

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

2.1 类成员的访问控制

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

  • internal:仅在自身程序集(Assembly)里面可以访问

  • public:从 程序集(Assembly) 暴露出去

Code Snippet

  1. F12:跳至类定义

  2. Ctrl + 减号(-):跳回至之前所在位置

3 类的继承

类的继承:

  • 类在功能上的扩展(extend)
  • 只能有一个基类,但可以实现多个其接口
  • 类访问级别对继承的影响
  • sealed类不能被继承

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

  • 横向扩展:对类成员个数的扩充

  • 纵向扩展:不增加类成员的个数,对类成员(重写)版本的更新

namespace HelloClass
{
    class Program
    {
        static void Main(string[] args)
        {
            RaceCar raceCar = new RaceCar();
            Console.WriteLine(raceCar.Owner); 
        }
    }

    class Vehicle
    {
        public Vehicle()
        {
            this.Owner = "N/A";//先运行基类对象
        }
        public string Owner { get; set; }
    }

    class Car:Vehicle
    {
        public Car()
        {
            Owner = "Car owner";//再运行子类对象。本次输出结果为Car owner
        }
    }

    class RaceCar:Car
    {

    }
}

先运行基类对象,再运行子类对象

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

namespace HelloClass
{
    class Program
    {
        static void Main(string[] args)
        {
            Type t = typeof(Car);
            Type tb = t.BaseType;
            Type tTop = tb.BaseType;
            Console.WriteLine(tTop.BaseType == null);
        }
    }

    class Vehicle:Object//未定义基类则都是通过Object派生而来,System.Object处于所有类型的继承链的顶端
    {

    }

    class Car:Vehicle
    {

    }
}

is a 概念

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

namespace HelloClass
{
    class Program
    {
        static void Main(string[] args)
        {
            Car car = new Car();
            Console.WriteLine(car is Vehicle);
            Console.WriteLine(car is Object);

            Vehicle vehicle = new Vehicle();
            Console.WriteLine(vehicle is Car);
        }
    }

    class Vehicle
    {
    }

    class Car:Vehicle
    {
    }
}

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

知识点

  • sealed 封闭类,无法被继承

  • C# 只支持单继承

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

  • 子类的访问权限不能超越父类

类成员的访问级别

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

 

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

在团队合作中,自己写的类或方法不想被他人调用时,推荐的做法就是不用 public 进行修饰。
如果应该封装的成员没有封装,对方只要发现能够调用,又能解决问题,他就一定会去用,进而导致一些不确定的问题。

  • public

  • protected internal

  • internal

  • protected

  • private

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.( Private Protected 仅对程序集内的派生类可见)

面向对象的实现风格

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

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

Java 也是基于类的,让我们一撇 Java:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值