深入浅出关键字---base和this

本文将介绍以下内容:

  • 面向对象基本概念
  • base关键字深入浅出
  • this关键字深入浅出

1. 引言

new关键字引起了大家的不少关注,尤其感谢Anders Liu的补充,让我感觉博客园赋予的交流平台真的无所不在。所以,我们就有必要继续这个话题,把我认为最值得关注的关键字开展下去,本文的重点是访问关键字(Access Keywords):base和this。虽然访问关键字不是很难理解的话题,我们还是有可以深入讨论的地方来理清思路。还是老办法,我的问题先列出来,您是否做好了准备。

  1. 是否可以在静态方法中使用base和this,为什么?
  2. base常用于哪些方面?this常用于哪些方面?
  3. 可以base访问基类的一切成员吗?
  4. 如果有三层或者更多继承,那么最下级派生类的base指向那一层呢?例如.NET体系中,如果以base访问,则应该是直接父类实例呢,还是最高层类实例呢?
  5. 以base和this应用于构造函数时,继承类对象实例化的执行顺序如何? 

2. 基本概念

base和this在C#中被归于访问关键字,顾名思义,就是用于实现继承机制的访问操作,来满足对对象成员的访问,从而为多态机制提供更加灵活的处理方式。 

2.1 base关键字

其用于在派生类中实现对基类公有或者受保护成员的访问,但是只局限在构造函数、实例方法和实例属性访问器中,MSDN中小结的具体功能包括:

  • 调用基类上已被其他方法重写的方法。
  • 指定创建派生类实例时应调用的基类构造函数。 

2.2 this关键字

其用于引用类的当前实例,也包括继承而来的方法,通常可以隐藏this,MSDN中的小结功能主要包括:

  • 限定被相似的名称隐藏的成员
  • 将对象作为参数传递到其他方法
  • 声明索引器 

3. 深入浅出

 

3.1 示例为上

下面以一个小示例来综合的说明,base和this在访问操作中的应用,从而对其有个概要了解,更详细的规则和深入我们接着阐述。本示例没有完全的设计概念,主要用来阐述base和this关键字的使用要点和难点阐述,具体的如下: 

base和this示例
using System;

namespace Anytao.net.My_Must_net
{
    public class Action
    {
        public static void ToRun(Vehicle vehicle)
        {
            Console.WriteLine("{0} is running.", vehicle.ToString());
        }
    }

    public class Vehicle
    {
        private string name;
        private int speed;
        private string[] array = new string[10];

        public Vehicle()
        {
        }

        //限定被相似的名称隐藏的成员
        public Vehicle(string name, int speed)
        {
            this.name = name;
            this.speed = speed;
        }

        public virtual  void ShowResult()
        {
            Console.WriteLine("The top speed of {0} is {1}.", name, speed);
        }

        public void Run()
        {
            //传递当前实例参数
            Action.ToRun(this);
        }



        //声明索引器,必须为this,这样就可以像数组一样来索引对象
        public string  this[int param]
        {
            get{return array[param];}
            set{array[param] = value;}
        }
    }

    public class Car: Vehicle
    {
        //派生类和基类通信,以base实现,基类首先被调用
        //指定创建派生类实例时应调用的基类构造函数
        public Car()
            : base("Car", 200)
        { }

        public Car(string name, int speed)
            : this()
        { }

        public override void ShowResult()
        {
            //调用基类上已被其他方法重写的方法
            base.ShowResult();
            Console.WriteLine("It's a car's result.");
        }

    }

    public class Audi : Car
    {
        public Audi()
            : base("Audi", 300)
        { }

        public Audi(string name, int speed)
            : this()
        { 
        }

        public override void ShowResult()
        {
            //由三层继承可以看出,base只能继承其直接基类成员
            base.ShowResult();
            base.Run();
            Console.WriteLine("It's audi's result.");
        }
    }

    public class BaseThisTester
    {
        public static void Main(string[] args)
        {
            Audi audi = new Audi();
            audi[1] = "A6";
            audi[2] = "A8";
            Console.WriteLine(audi[1]);
            audi.Run();
            audi.ShowResult();
        }
    }
}

3.2 示例说明

上面的示例基本包括了base和this使用的所有基本功能演示,具体的说明可以从注释中得到解释,下面的说明是对注释的进一步阐述和补充,来说明在应用方面的几个要点:

  1. base常用于,在派生类对象初始化时和基类进行通信。
  2. base可以访问基类的公有成员和受保护成员,私有成员是不可访问的。
  3. this指代类对象本身,用于访问本类的所有常量、字段、属性和方法成员,而且不管访问元素是任何访问级别。因为,this仅仅局限于对象内部,对象外部是无法看到的,这就是this的基本思想。另外,静态成员不是对象的一部分,因此不能在静态方法中引用this。
  4. 在多层继承中,base可以指向的父类的方法有两种情况:一是有重载存在的情况下,base将指向直接继承的父类成员的方法,例如Audi类中的ShowResult方法中,使用base访问的将是Car.ShowResult()方法,而不能访问Vehicle.ShowResult()方法;而是没有重载存在的情况下,base可以指向任何上级父类的公有或者受保护方法,例如Audi类中,可以使用base访问基类Vehicle.Run()方法。

3.2 示例说明

上面的示例基本包括了base和this使用的所有基本功能演示,具体的说明可以从注释中得到解释,下面的说明是对注释的进一步阐述和补充,来说明在应用方面的几个要点:

  1. base常用于,在派生类对象初始化时和基类进行通信。
  2. base可以访问基类的公有成员和受保护成员,私有成员是不可访问的。
  3. this指代类对象本身,用于访问本类的所有常量、字段、属性和方法成员,而且不管访问元素是任何访问级别。因为,this仅仅局限于对象内部,对象外部是无法看到的,这就是this的基本思想。另外,静态成员不是对象的一部分,因此不能在静态方法中引用this。
  4. 在多层继承中,base可以指向的父类的方法有两种情况:一是有重载存在的情况下,base将指向直接继承的父类成员的方法,例如Audi类中的ShowResult方法中,使用base访问的将是Car.ShowResult()方法,而不能访问Vehicle.ShowResult()方法;而是没有重载存在的情况下,base可以指向任何上级父类的公有或者受保护方法,例如Audi类中,可以使用base访问基类Vehicle.Run()方法。

 

3.3 深入剖析 

如果有三次或者更多继承,那么最下级派生类的base指向那一层呢?例如.NET体系中,如果以base访问,则应该是直接父类实例呢,还是最高层类实例呢?

首先我们有必要了解类创建过程中的实例化顺序,才能进一步了解base机制的详细执行过程。一般来说,实例化过程首先要先实例化其基类,并且依此类推,一直到实例化System.Object为止。因此,类实例化,总是从调用System.Object.Object()开始。因此示例中的类Audi的实例化过程大概可以小结为以下顺序执行,详细可以参考示例代码分析。

  1. 执行System.Object.Object();
  2. 执行Vehicle.Vehicle(string name, int speed);
  3. 执行Car.Car();
  4. 执行Car.Car(string name, int speed);
  5. 执行Audi.Audi();
  6. 执行Audi.Audi(string name, int speed)。

我们在充分了解其实例化顺序的基础上就可以顺利的把握base和this在作用于构造函数时的执行情况,并进一步了解其基本功能细节。

你可能感兴趣的:(this)