CodeSnippet.Cn
代码片段
Csharp
架构设计
.NetCore
西班牙语
kubernetes
MySql
Redis
Algorithm
Ubuntu
Linux
Other
.NetMvc
VisualStudio
Git
pm
Python
WPF
java
Plug-In
分布式
CSS
微服务架构
JavaScript
DataStructure
Shared
C# 8.0 的默认接口方法
0
Csharp
小笨蛋
发布于:2022年01月28日
更新于:2022年01月28日
95
#custom-toc-container
例子 直接看例子 有这样一个接口: ![图片alt](/uploads/images/20220128/121819-7893c71fe419483c8883d0e1d45a9b59.png ''代码片段:Www.CodeSnippet.Cn'') 然后有三个它的实现类: ![图片alt](/uploads/images/20220128/121843-79dbe493f83940089b597f3c9ddba278.png ''代码片段:Www.CodeSnippet.Cn'') 然后在main方法里面调用: ![图片alt](/uploads/images/20220128/121854-259451e1ea98454ebbdc44c1d6c4f5c4.png ''代码片段:Www.CodeSnippet.Cn'') 截至目前,程序都可以成功的编译和运行。 ### IPerson接口变更 突然,我想对所有的人类添加一个新的特性,例如,添加一个自我介绍的方法,所以我在`IPerson`里添加了`Introduce()`这个方法: ![图片alt](/uploads/images/20220128/121917-766b0718cce94886a35b7e3f35b311ab.png ''代码片段:Www.CodeSnippet.Cn'') 现在再次Build一下项目,肯定会失败的: ![图片alt](/uploads/images/20220128/121939-94ac00278dd04a149be04fc1080d66a0.png ''代码片段:Www.CodeSnippet.Cn'') 因为这个方法在三个实现类里面都没有实现。 使用默认的实现来更新接口 如果在C# 8.0以前,我们肯定需要把三个实现类都实现一下这个`Introduce()` 方法。而在C# 8.0里,我们可以在`IPerson`接口里做一个默认的方法实现: ![图片alt](/uploads/images/20220128/122012-4d33c0e77f7e41af92bf2f2219dc2883.png ''代码片段:Www.CodeSnippet.Cn'') 再次Build之后,您会发现就没有错误了: ![图片alt](/uploads/images/20220128/122025-985b85bb20094c36a614a7033674e404.png ''代码片段:Www.CodeSnippet.Cn'') 而且我们也可以在所有的实现类上正常的调用这个方法: ![图片alt](/uploads/images/20220128/122100-b299c1b6ce434ece88efb171b3a32f14.png ''代码片段:Www.CodeSnippet.Cn'') ![图片alt](/uploads/images/20220128/122110-fe0a82c9ebfc4bf89fe523741b0bcdc0.png ''代码片段:Www.CodeSnippet.Cn'') 我没有设置任何属性,但是结果是没问题的。 但是,不可以直接在实现类上调用该方法,例如这样写就会报错: ![图片alt](/uploads/images/20220128/122125-b3eb00adccd847cc978eb85d9fc0f243.png ''代码片段:Www.CodeSnippet.Cn'') 这是因为Teacher这个实现类并没有定义`Introduce()`这个方法。 在前面的例子的里,我是通过`IPerson`接口调用的这个方法,这是没有问题的,因为`IPerson`这个接口定义了这个方法。 ### 接口的静态成员 上面例子的输出是这样的: ![图片alt](/uploads/images/20220128/122146-840e5aa1f7f047eeb86f76d7de004c01.png ''代码片段:Www.CodeSnippet.Cn'') 而我想让输出有默认的名字和年龄,在C# 8.0里面,我们可以这样做,添加静态字段(`field`)和静态方法: ![图片alt](/uploads/images/20220128/122227-1187004368e1470fb62403a0dca57afd.png ''代码片段:Www.CodeSnippet.Cn'') 实际上这个不会报错的,出现红色波浪线的原因可能是因为我的`Resharper`和VS没有升级,Build会成功的。 这里面我做的有点“脱裤子放屁”,但我仅仅是为了展示语言的新特性。 然后在调用的时候,我们可以在`IPerson`接口上先设置默认值: ![图片alt](/uploads/images/20220128/122248-8813ddd6c89347efa0922f974b3bd716.png ''代码片段:Www.CodeSnippet.Cn'') 然后运行: ![图片alt](/uploads/images/20220128/122300-000e02b602fd4ae3b8785ab792160e76.png ''代码片段:Www.CodeSnippet.Cn'') 可以看到,由于各个实现类都没有自己的实现,所以都输出了默认值。 ### 在类上实现接口方法 在Teacher类上实现`Introduce()`这个方法: ![图片alt](/uploads/images/20220128/122326-6cf404cd4e22447a9b2b815591601a78.png ''代码片段:Www.CodeSnippet.Cn'') 然后就可以调用`Teacher`上的`Introduce()`方法了: ![图片alt](/uploads/images/20220128/122344-abed8de844eb4cbebda4d1b1d998ff39.png ''代码片段:Www.CodeSnippet.Cn'') 运行程序: ![图片alt](/uploads/images/20220128/122355-6b42c61e32984f488d81148bc5f5233a.png ''代码片段:Www.CodeSnippet.Cn'') 可以看到无论是通过`Teacher`类的实例还是通过`IPerson`接口,最终调用的都是`Teacher`类实现的`Introduce()`方法。
这里⇓感觉得写点什么,要不显得有点空,但还没想好写什么...
返回顶部
About
京ICP备13038605号
© 代码片段 2024