C#中的virtual,abstract,override和new关键字

简介: C#中virtual,abstract,override用于方法重载,子类覆盖了父类的相同方法,父类中的实现不可能再被外面调用。 new的作用是投影(shadowing),子类隐藏了父类的相同方法,通过强制类型转换外面还可以调用父类的实现。
C#中virtual,abstract,override用于方法重载,子类覆盖了父类的相同方法,父类中的实现不可能再被外面调用。
new的作用是投影(shadowing),子类隐藏了父类的相同方法,通过强制类型转换外面还可以调用父类的实现。

下面是重载的例子
Code:

点击(此处)折叠或打开

  1. class Parent
  2.     {
  3.         public virtual Parent foo()
  4.         {
  5.             System.Console.WriteLine("Parent.foo()");
  6.             return this;
  7.         }
  8.     }

  9.     class Child : Parent
  10.     {
  11.         public override Parent foo()
  12.         {
  13.             System.Console.WriteLine("Child.foo()");
  14.             return this;
  15.         }
  16.     }

Test:

点击(此处)折叠或打开

  1. class Program
  2.     {
  3.         static void Main(string[] args)
  4.         {
  5.             Child c =new Child();
  6.             c.foo();
  7.             ((Parent)c).foo();
  8.         }
  9.     }
Result:
Child.foo()
Child.foo()

下面是投影的例子
Code:

点击(此处)折叠或打开

  1. class Parent
  2.     {
  3.         public Parent foo()
  4.         {
  5.             System.Console.WriteLine("Parent.foo()");
  6.             return this;
  7.         }
  8.     }

  9.     class Child : Parent
  10.     {
  11.         public new Child foo()
  12.         {
  13.             System.Console.WriteLine("Child.foo()");
  14.             return this;
  15.         }
  16.     }

Test:

点击(此处)折叠或打开

  1. class Program
  2.     {
  3.         static void Main(string[] args)
  4.         {
  5.             Child c =new Child();
  6.             c.foo();
  7.             ((Parent)c).foo();
  8.         }
  9.     }
Result:
Child.foo()
Parent.foo()

重载的规则:
  1. 父类提供实现,则父类使用virtual关键字
  2. 父类不提供实现,则父类自身和相关方法使用abstract关键字,此时子类必须提供实现
  3. 子类重载需使用override关键字,如省略当作new(即投影)处理,并且编译器报编译警告
  4. 重载时子类方法不能改写返回值类型
  5. 子类中可以使用base关键字引用父类的实现

投影的规则:
  1. 父类必须提供实现(甚至可以有virtual关键字)
  2. 子类应该使用new关键字,如省略也当作new处理,但编译器报编译警告
  3. 投影时子类方法可以改写返回值类型
  4. 子类中可以使用base关键字引用父类的实现

除此以外还有一种接口投影的情况,通过接口投影可以新定义一个和接口定义同名同参但不同返回类型的函数。
比如:
Code:

点击(此处)折叠或打开

  1. interface MyInterface
  2.     {
  3.         Object foo();
  4.     }

  5.     class MyImp : MyInterface
  6.     {
  7.         Object MyInterface.foo()
  8.         {
  9.             System.Console.WriteLine("MyInterface.foo()");
  10.             return null;
  11.         }

  12.         public MyImp foo()
  13.         {
  14.             System.Console.WriteLine("foo()");
  15.             return null;
  16.         }
  17.     }

Test:

点击(此处)折叠或打开

  1. MyImp myImp = new MyImp();
  2.     myImp.foo();
  3.     ((MyInterface)myImp).foo();

Result:
foo()
MyInterface.foo()






相关文章
|
2月前
|
开发框架 Cloud Native .NET
10 个 C# 关键字和功能
10 个 C# 关键字和功能
60 8
|
4月前
|
C# 索引
C#中的virtual和override关键字
C#中的virtual和override关键字
51 3
|
4月前
|
开发框架 .NET C#
【Azure Developer】C# / .NET 静态函数中this关键字的作用
【Azure Developer】C# / .NET 静态函数中this关键字的作用
|
4月前
|
C# 计算机视觉
C#中out关键字
C#中out关键字
66 0
|
4月前
|
编译器 C# 计算机视觉
C#中的ref关键字
C#中的ref关键字
62 0
|
7月前
|
开发框架 前端开发 .NET
C#编程与Web开发
【4月更文挑战第21天】本文探讨了C#在Web开发中的应用,包括使用ASP.NET框架、MVC模式、Web API和Entity Framework。C#作为.NET框架的主要语言,结合这些工具,能创建动态、高效的Web应用。实际案例涉及企业级应用、电子商务和社交媒体平台。尽管面临竞争和挑战,但C#在Web开发领域的前景将持续拓展。
219 3
|
1月前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
36 3
|
5天前
|
存储 安全 编译器
学懂C#编程:属性(Property)的概念定义及使用详解
通过深入理解和使用C#的属性,可以编写更清晰、简洁和高效的代码,为开发高质量的应用程序奠定基础。
36 12
|
1月前
|
设计模式 C# 图形学
Unity 游戏引擎 C# 编程:一分钟浅谈
本文介绍了在 Unity 游戏开发中使用 C# 的基础知识和常见问题。从 `MonoBehavior` 类的基础用法,到变量和属性的管理,再到空引用异常、资源管理和性能优化等常见问题的解决方法。文章还探讨了单例模式、事件系统和数据持久化等高级话题,旨在帮助开发者避免常见错误,提升游戏开发效率。
52 4
|
3月前
|
API C#
C# 一分钟浅谈:文件系统编程
在软件开发中,文件系统操作至关重要。本文将带你快速掌握C#中文件系统编程的基础知识,涵盖基本概念、常见问题及解决方法。文章详细介绍了`System.IO`命名空间下的关键类库,并通过示例代码展示了路径处理、异常处理、并发访问等技巧,还提供了异步API和流压缩等高级技巧,帮助你写出更健壮的代码。
53 2