c#之类的继承,类成员的访问控制

引自于:https://www.bilibili.com/video/BV1wx411K7rb?p=26

注意:在类设计的时候,一定要对成员的访问级别做限制。比如做一个交通工具类,在使用交通工具的时候需要加油和烧油,此时必须要要对烧油这个方法做限制,可以限制为交通工具类及其派生类才能调用的方法,因为这个方法不是谁都能做的,只能是交通工具内部自己操作的,不会由人来操作。尤其是在多人共同做项目的情况下,别人用不到的方法一定不能让开放给别人,避免不必要的问题。

1.继承

 (1)继承是单根的,一个基类的变量可以引用其派生类的实例,比如:       Vehicle vehicle = new Car();

 我们可以说一个交通工具是一个对象,一个车是交通工具,一个车是一个对象,这都是没问题的。

可以看下面代码:

 class Program
    {
        static void Main(string[] args)
        {
            //vehicle是Vehicle的对象,引用的是Car类的实例
            Vehicle vehicle = new Car();
            // 一个车是一个对象
            Object obj = new Car();
            //一个交通工具是一个对象
            Object objVehicle = new Vehicle();

            Console.WriteLine(vehicle is Car);
            Console.WriteLine(obj is Car);
            Console.WriteLine(vehicle is Vehicle);
            Console.ReadKey();
        }
    }

    /// <summary>
    /// 交通工具类
    /// </summary>
    class Vehicle
    {

    }

    class Car : Vehicle
    {

    }

结果:

True
True
True

(2)sealed类为密封类,不可以被继承,但是一个子类可以继承多个接口

(3)子类的访问级别不能超过基类的访问级别。

注意:

public级别,作用域是整个解决方案。

internal级别,作用域是整个装配集(Assembly),默认不加修饰符的都是internal级别

protected级别,作用域是整个解决方案中以它自己的类为基类以及它的派生类,不在继承链上的类则不能访问

private级别,作用域是它自己的类内部(class)

需要注意的,类成员的访问级别是以类的访问级别为上限的。比如类是internal级别,就算是类内部就public级别的成员,在其他assembly(程序集)中也是看不到这个成员的,因为连这个类都看不到。

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

1.派生类可以继承基类已有的成员。在派生和继承的过程当中,我们进行的是扩展。扩展的意思是在继承过程中,类成员只可能越来越多,不可能越来越少。

也就是说,当把一个成员引用到这个继承链当中,是会一直往下传递,不可能去掉(当然在不运行代码的时候可以直接删掉),所以 要慎重。比如c++,c#,java这些静态语言都是这样的,但是动态语言如javascript可以动态移除添加。

2.横向扩展指的是增加派生类的成员,可以理解成一个人吃的越多越胖。

3.纵向扩展可以理解成不断更新的版本,从基类这个最初的版本向下更新。

4。在继承中,实例构造器是不被继承的。所以基类有构造函数的时候,派生类都不会继承。

看下面代码,首先 ,Car已经创建了一个带参数的构造函数,所以就不会默认创建无参数的构造函数的方法了,所以在实例化的时候必须带参数,否则报错。

其次,在派生类(派生类中初始化了构造函数)实例化的时候会先调用基类的构造函数,然后调用离基类最近的派生类的的构造函数,一直到当前类的构造函数,从上往下。

还有,在派生类中可以使用base调用父类(不是基类)的成员,职称调用离当前类最近的父类的成员,不可能调用父类的父类.....。

  class Program
    {
        static void Main(string[] args)
        {
            //注意:第一点是Car已经创建了一个带参数的构造函数,所以
            Car car = new Car("初始车");

            RaceCar raceCar = new RaceCar("加速车");
           // Console.WriteLine(vehicle is Vehicle);
            Console.ReadKey();
        }
    }

    /// <summary>
    /// 交通工具类
    /// </summary>
    class Vehicle
    {
        public string Owner { get; set; }
        /// <summary>
        /// 有参数的构造函数,注意,此时Vehicle这个类就不会再默认创建无参数的构造函数了。
        /// </summary>
        /// <param name="owner"></param>
        public Vehicle(string owner)
        {
            Owner = owner;
        }

    }

    class Car : Vehicle
    { 
        /// <summary>
        /// 汽车类构造函数
        /// </summary>
        /// <param name="owner"></param>
        public Car(string owner):base(owner)
        {
           
        }
       

    }
    class RaceCar : Car
    {
        /// <summary>
        /// 汽车类构造函数
        /// </summary>
        /// <param name="owner"></param>
        public RaceCar(string owner) : base(owner)
        {

        }
        public void Test()
        {
            string test = base.Owner;
        }

    }

下面代码可以证明car的基类:

namespace 重写多态
{
    class Program
    {
        static void Main(string[] args)
        {
            //可以通过下面代码证明Car继承了Vehicle
            Type type = typeof(Car);
            Type t = type.BaseType;//寻找继承的基类 
            Console.WriteLine(t.FullName);
            Console.ReadKey();
        }
    }

    //基类
    class Vehicle
    {

    }
    
    class Car : Vehicle
    {

    }

}

 结果:

重写多态.Vehicle
原文地址:https://www.cnblogs.com/anjingdian/p/13090455.html