假设有下面的设计:
cs
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public int Height { get;}
}
public class Chinese: Person
{
public new int Height { get => 100; }
}
基类中Height属性设计为只读,派生类中设计为可读可写,并且使用new进行覆盖;
有下方代码:
cs
Person me = new Chinese();
var height = me.Height;
此时me.Height返回0;
因为声明me的时候使用的是Person类型,而Person里面Height属性的Get方法是实现的,访问的自然是Person里面Height属性,Height属性为int类型,所以初始值为0;
类似的,这个结论对于方法也适用,加入把实体像下面这样设计:
cs
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public int Height { get;}
public int GetHeight()
{
return 0;
}
}
public class Chinese: Person
{
public new int Height { get => 100; }
public new int GetHeight()
{
return 100;
}
}
然后调用GetHeight方法:
cs
Person me = new Chinese();
var height = me.GetHeight();
返回的height依旧是0;
想实现me.Height访问的是Chinese里面的属性,可以把实体像下面这样设计:
cs
public abstract class Person
{
public string Name { get; set; }
public int Age { get; set; }
public abstract int Height { get;}
}
public class Chinese: Person
{
public override int Height { get => 100; }
}
或者:
cs
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public virtual int Height { get;}
}
public class Chinese: Person
{
public override int Height { get => 100; }
}
以上两种情况返回值就会是100;
由以上三种情况,针对new abstract virtual三种实现多态的关键字,在访问成员时有以下结论:
//普通方法的调用(使用new时, 调用左边类型的方法;编译时确定
//虚方法的调用,调用右边类型的方法(没有override 还是左边);运行时确定;
//抽象方法的调用,调用右边类型的方法;运行时确定;