加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

[你必须知道的.NET] 第六回:深入浅出关键字---base和this

发布时间:2020-12-15 21:12:08 所属栏目:asp.Net 来源:网络整理
导读:div style="FONT-SIZE: 10pt" 面向对象基本概念 base关键字深入浅出 this关键字深入浅出 是否可以在静态方法中使用base和this,为什么? base常用于哪些方面?this常用于哪些方面? 可以base访问基类的一切成员吗? 如果有三层或者更多继承,那么最下级派生

<div style="FONT-SIZE: 10pt">

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

  1. 是否可以在静态方法中使用base和this,为什么?
  2. base常用于哪些方面?this常用于哪些方面?
  3. 可以base访问基类的一切成员吗?
  4. 如果有三层或者更多继承,那么最下级派生类的base指向那一层呢?例如.NET体系中,如果以base访问,则应该是直接父类实例呢,还是最高层类实例呢?
  5. 以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();????????}????}}

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

  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)。

.method?public?hidebysig?static?void??Main(string[]?args)?cil?managed{??.entrypoint??//?代码大小???????61?(0x3d)??.maxstack??3??.locals?init?(class?Anytao.net.My_Must_net.Audi?V_0)??IL_0000:??nop??//使用newobj指令创建新的对象,并调用构造函数初始化??IL_0001:??newobj?????instance?void?Anytao.net.My_Must_net.Audi::.ctor()??IL_0006:??stloc.0??IL_0007:??ldloc.0??IL_0008:??ldc.i4.1??IL_0009:??ldstr??????"A6"??IL_000e:??callvirt???instance?void?Anytao.net.My_Must_net.Vehicle::set_Item(int32,??????????????????????????????????????????????????????????????????????????????string)??IL_0013:??nop??IL_0014:??ldloc.0??IL_0015:??ldc.i4.2??IL_0016:??ldstr??????"A8"??IL_001b:??callvirt???instance?void?Anytao.net.My_Must_net.Vehicle::set_Item(int32,??????????????????????????????????????????????????????????????????????????????string)??IL_0020:??nop??IL_0021:??ldloc.0??IL_0022:??ldc.i4.1??IL_0023:??callvirt???instance?string?Anytao.net.My_Must_net.Vehicle::get_Item(int32)??IL_0028:??call???????void?[mscorlib]System.Console::WriteLine(string)??IL_002d:??nop??IL_002e:??ldloc.0??IL_002f:??callvirt???instance?void?Anytao.net.My_Must_net.Vehicle::Run()??IL_0034:??nop??IL_0035:??ldloc.0??//base.ShowResult最终调用的是最高级父类Vehicle的方法,??//而不是直接父类Car.ShowResult()方法,这是应该关注的??IL_0036:??callvirt???instance?void?Anytao.net.My_Must_net.Vehicle::ShowResult()??IL_003b:??nop??IL_003c:??ret}?//?end?of?method?BaseThisTester::Main

  • 尽量少用或者不用base和this。除了决议子类的名称冲突和在一个构造函数中调用其他的构造函数之外,base和this的使用容易引起不必要的结果。
  • 在静态成员中使用base和this都是不允许的。原因是,base和this访问的都是类的实例,也就是对象,而静态成员只能由类来访问,不能由对象来访问。
  • base是为了实现多态而设计的。
  • 使用this或base关键字只能指定一个构造函数,也就是说不可同时将this和base作用在一个构造函数上。
  • 简单的来说,base用于在派生类中访问重写的基类成员;而this用于访问本类的成员,当然也包括继承而来公有和保护成员。
  • 除了base,访问基类成员的另外一种方式是:显示的类型转换来实现。只是该方法不能为静态方法。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读