C#:(补)this和base的区别
这一篇是补给C#:类的继承的。
由于在写这篇的时候,发现base和this在访问同一成员的时候编译期提示颜色变成灰色,所以才决定将base和this的区别查一下
微软官方给出的base的介绍其实就是base和this的区别:base关键字
调用基类上被其它方法重写的方法--准确来说是在子类中使用base可以调用基类中那个"原生"方法
namespace ExtendsDemo
{
class Program
{
static void Main(string[] args)
{
Shape square = new Square();
Console.ReadLine();
}
}
class Shape
{
public double Area { get; set; }
public string Color { get; set; }
//使用virtual表明 该函数成员的功能希望在子类中被更新
public virtual void ShowInfo()
{
Console.WriteLine($"面积:{Area},颜色:{Color}");
}
}
class Square : Shape
{
public Square()
{
base.ShowInfo();
this.ShowInfo();
}
public override void ShowInfo()
{
Console.WriteLine("我是长方形,对边相等且平行...");
}
}
}
/*输出:
面积:0,颜色:
我是长方形,对边相等且平行...
*/
base的第一点作用,重在描述base的能力:如果子类重写了父类函数成员,那么在子类中如果不用base,试问还有谁还能访问到基类中那个“原生”方法?(this么?试一下就知道不行--这就是this和base的第一点区别)虽然明白了base有这种作用,但是我却并不知道这个作用在实际编码中有什么用.....
指定创建派生类实例时应调用的基类构造函数
- 在创建子类实例的时候,由于C#要求必须要先调用基类构造函数,如果基类没有提供构造函数还好(编译器会帮我们隐式调用基类默认构造函数)
- 但如果基类型没有提供默认构造函数,只是提供了一些带参构造函数,那么编译器可不知道我们要调用哪一个(从下图的报错信息可知:这种情况下编译器不帮我们隐式调用默认构造函数了)
- 这时base作为拥有"可以在子类中调用基类构造函数"的能力,华丽出场
namespace ExtendsDemo
{
class Program
{
static void Main(string[] args)
{
Shape square = new Square();
square.ShowInfo();
Console.ReadLine();
}
}
class Shape
{
public double Area { get; set; }
public string Color { get; set; }
public Shape(double area)
{
this.Area = area;
}
public Shape(double area,string color)
{
this.Area = area;
this.Color = color;
}
//使用virtual表明 该函数成员的功能希望在子类中被更新
public virtual void ShowInfo()
{
Console.WriteLine($"面积:{Area},颜色:{Color}");
}
}
class Square : Shape
{
public Square():base(12.3)//访问基类单参数的构造函数
{
}
public Square(double area,string color):base(area,color)//访问基类两个参数的构造函数
{
}
public override void ShowInfo()
{
base.ShowInfo();
Console.WriteLine("我是长方形,对边相等且平行...");
}
}
}
/*输出:
面积:12.3,颜色:
我是长方形,对边相等且平行...
*/
上面展示了base的第二种能力,这勉强算是base和this的第二个区别吧?
成员如果被new修饰,base和this都访问这个成员,此时base、this也是有区别的:
namespace ExtendsDemo
{
class Program
{
static void Main(string[] args)
{
Shape square = new Square();
Console.ReadLine();
}
}
class Shape
{
public double Area { get; set; }
public string Color { get; set; }
public Shape(double area)
{
this.Area = area;
}
//使用virtual表明 该函数成员的功能希望在子类中被更新
public virtual void ShowInfo()
{
Console.WriteLine($"面积:{Area},颜色:{Color}");
}
}
class Square : Shape
{
public Square() : base(12.3)
{
base.ShowInfo();//base已经不是灰色了,表示base和this访问的成员不一样了。
this.ShowInfo();
}
//ShowInfo成员被new修饰,导致这个Square的ShowInfo和Shape的ShowInfo不一致
public new virtual void ShowInfo()
{
Console.WriteLine("我是长方形,对边相等且平行...");
}
}
}
/*输出:
面积:12.3,颜色:
我是长方形,对边相等且平行...
*/
如果你看了我写的C#:多态,就知道为什么new会产生如此现象--总之不建议在继承链中使用new,修饰函数成员
非以上描述情况,使用base和this访问同一成员,没有区别:这时base和this可以不写。
namespace ExtendsDemo
{
class Program
{
static void Main(string[] args)
{
Shape square = new Square();
Console.ReadLine();
}
}
class Shape
{
public int cost;
public double Area { get; set; }
public string Color { get; set; }
public Shape(double area)
{
this.Area = area;
}
public virtual void ShowInfo()
{
Console.WriteLine($"面积:{Area},颜色:{Color}");
}
}
class Square : Shape
{
public Square() : base(12.3)
{
Console.WriteLine(base.cost+"---"+this.cost);//base和this访问数据成员时没有却区别
Console.WriteLine(base.Area+"---"+this.Area);//base和this访问普通的函数成员时也没有区别
}
public override void ShowInfo()
{
Console.WriteLine("我是长方形,对边相等且平行...");
}
}
}
/*输出:
0---0
12.3---12.3
*/
以上便是对base和this的区别的总结,记录下来以便以后查阅。