C# 继承中的使用new的陷阱,和abstract /virtual 的不同

假设有下面的设计:

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 还是左边);运行时确定;

//抽象方法的调用,调用右边类型的方法;运行时确定;

相关推荐
死磕音视频7 小时前
让小模型做选择题:限定候选项并读取 logits 概率的入门实践(附 Python 代码)
开发语言·python·大模型·文本分类·transformers
顽疲9 小时前
Java vue 养老系统源码详解:月账单 care_month_bill 与 Quartz 扣费 Job 实践
java·开发语言·vue.js·vue养老·springboot养老·java养老
Wang's Blog10 小时前
Java 项目实战: 交友项目 - 安装开发工具与环境准备
java·开发语言·交友
曹牧10 小时前
C#:输入的字符串格式不正确
c#
程序喵大人11 小时前
【C++入门】编译链接模型 - 07 链接器怎样把符号对上号
开发语言·c++·编译器·编译链接·链接器
微三云 - 廖会灵 (私域系统开发)12 小时前
供应链系统实战:多渠道订单聚合与分布式库存一致性方案总结
开发语言·分布式·php
学逆向的12 小时前
C 数据溢出与精度丢失
c语言·开发语言·网络安全
霸道流氓气质13 小时前
AgentFlow 入门与实战:Task-Based 并发、EWMA 动态调度与四道门禁的 Java 生产级编排
java·开发语言
释厄62313 小时前
错误无误公理——错误正确本同源都迭代定律——逆转有价值
android·开发语言·kotlin
2601_9628857213 小时前
如何用 Python计算 CR能量指标(中间意愿指标)?
开发语言·python