基本概念
base
和this
在 C# 中被归为访问关键字,其目的就是实现继承
机制的访问操作,来满足对象成员的访问,为多态
机制提供更灵活的处理方式。
直接看例子
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);
}
public string this[int param]
{
get { return array[param]; }
set { array[param] = value; }
}
}
首先创建了两个类一个Action
和Vehicle
类来模拟汽车的运行。
这里可以看到Vehicle
类中出现的this
。
this.name=name
Action.ToRun(this);
这里出现的两个this
含义是一样的都代表Vehicle类
本身。
public string this[int param]
{
get { return array[param]; }
set { array[param] = value; }
}
这里的this就是Vehicle
中的string[]
数组。
方法中的get
、set
分别用于数组的 取值、赋值 。
接下来我们创建一个Car类
,具体代码如下:
public class Car : Vehicle
{
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.");
}
}
创建的Car类
继承Vehicle类
,所有base
是Vehicle
类,而this
是Car
类。
这里可以看到第一个Car的构造函数base
被赋值"Car"
和200
,并且重写了Vehicle
类的ShowResult
方法。
方法中在原来的基础上base.ShowResult();
加上了 Console.WriteLine("It's a car's result.");
。
接下来在创建一个Audi类,代码如下:
public class Audi : Car
{
public Audi() : base("Audi", 300) { }
public Audi(string name, int speed) : this() { }
public override void ShowResult()
{
base.ShowResult();
base.Run();
Console.WriteLine("It's audi's result.");
}
}
创建的Audi类
继承Car类
,那里面的base
是基类Car
还是基类的基类Vehicle
呢?答案是前者。
所以下面重写的ShowResult
方法中的base.ShowResult
是Car
中重写的ShowResult
而不是Vehicle
。
最后我们在来运行下:
public static void Main(string[] args)
{
Audi audi = new Audi();
audi[1] = "A6";
audi[2] = "A8";
Console.WriteLine(audi[1]);
audi.Run();
audi.ShowResult();
Console.Read();
}
输出的结果如下:
A6
Test.Program+Audi is running.
The top speed of Car is 200.
It's a car's result.
Test.Program+Audi is running.
It's audi's result.
总结
用法如下几点:
-
base
常用于,在派生类对象初始化时和基类进行通信。 -
base
可以访问基类的公有成员和受保护成员,私有成员是不可访问的。 -
this
指代类对象本身,用于访问本类的所有常量、字段、属性和方法成员,而且不管访问元素是任何访问级别。因为,this
仅仅局限于对象内部,对象外部是无法看到的,这就是this
的基本思想。另外,静态成员不是对象的一部分,因此不能在静态方法中引用this
。 - 在多层继承中,
base
可以指向的父类的方法有两种情况:一是有重载存在的情况下,base
将指向直接继承
的父类成员的方法如上:ShowResult方法
;二是没有重载存在的情况下,base
可以指向任何上级父类的公有或者受保护方法如上:Run()方法,毕竟Car已经继承了Vehicle也享有Run()方法
。
但值得关注的一点是在运行时最终指向的是最高基类的成员,也就是例子中
Vehicle
的ShowResult()
方法。
通用规则:
- 尽量少用或者不用base和this。除了决议子类的名称冲突和在一个构造函数中调用其他的构造函数之外,base和this的使用容易引起不必要的结果。
- 在静态成员中使用base和this都是不允许的。原因是,base和this访问的都是类的实例,也就是对象,而静态成员只能由类来访问,不能由对象来访问。
- base是为了实现多态而设计的。
- 使用this或base关键字只能指定一个构造函数,也就是说不可同时将this和base作用在一个构造函数上。
- 简单的来说,base用于在派生类中访问重写的基类成员;而this用于访问本类的成员,当然也包括继承而来公有和保护成员。
- 除了base,访问基类成员的另外一种方式是:显示的类型转换来实现。只是该方法不能为静态方法。
引文
[你必须知道的.NET] 第六回:深入浅出关键字---base和this
END
- 如果文章内容能误导大家那真是再好不过了,嘻嘻嘻。
- 文章内容可能持续变更,修改或添加更多内容,以确保内容的准确性。
- 文章中大部分观点来自引文的总结,写文章的初衷是为了方便回忆。
- 更新时间:2018-10-10
网友评论