C# 在基类定义好方法让子类继承接口就能实现
在 C# 里面,接口的定义只需要类里面存在和接口声明相同的方法或属性就可以,而存在的方法或属性是在子类定义的还是基类里面定义的都无所谓。也就是在基类里面写好了方法,但不继承接口,等子类继承接口的时候就不需要子类实现方法。通过这样的方法可以在基类里面添加一些辅助方法,而这些方法默认不给子类开启,除非子类继承了接口
在基类定义的方法,如果在子类继承的接口里面声明的方法刚好和基类定义的相同,那么子类可以不需要再次定义。在基类可以判断当前自己的类型是否继承了接口
这个方法用在基类里面期望在特定的代码里面给子类暴露一些内部的方法,但是又不能让子类随意调用。或者预设了一些方法,这些方法存在性能或其他的问题,只有子类声明自己需要这个功能的时候才被调用
内部方法隐藏
在基类里面有一些内部的方法,默认不让子类使用的,但只有某些特殊的子类的情况才能被使用。同时这些内部方法还可能被外部的其他方法调用,不一定是子类
按照以上的约定就可以写出如下代码
public interface ILindexiDb
{
string GetPrivateString();
}
public class BassClass
{
public string GetPrivateString()
{
if (!(this is ILindexiDb))
{
throw new NotSupportedException("这个方法除非是林德熙逗比才能使用,其他人不能使用");
}
return "林德熙是逗比";
}
}
从代码可以看到,除非这个类继承了 ILindexiDb 不然 GetPrivateString 方法将会异常,因为我期望这个方法只有我才能调用
那么假如我有一个 Foo 的接口里面就需要使用到对应的方法,而默认业务想要返回的方法是基类定义的上面的方法
public interface IFoo
{
void GetString();
}
不明真相的小伙伴可能会如何写?
public class Foo : BassClass, IFoo
{
public void GetString()
{
Console.WriteLine(GetPrivateString());
}
}
上面代码是小伙伴会直接写出的代码,然而这段代码没有运行的时候就会炸,原因是在基类判断当前这个类没有继承林德熙是逗比这个接口
在我将基类放在一个程序集编译为dll之后,小伙伴没有方法直接看到源代码,他在调用 GetPrivateString 方法的时候抛出了方法没有支持异常,于是小伙伴会认为这个方法还没实现,她就不会想要去使用这个方法
而林德熙逗比将会写出下面代码用来访问内部的方法
public class Foo2 : BassClass, ILindexiDb, IFoo
{
public void GetString()
{
Console.WriteLine(GetPrivateString());
}
}
因为注入的都是 IFoo 接口,小伙伴都不知道实际实现的 Foo2 里面做了什么,如果不信,请在 VisualStudio 里面用上代码,然后调试一下。此时很难知道 Foo2 里面做了什么魔法让调用 GetPrivateString 方法不会异常,因为在调试的时候是很难知道当前这个类继承了哪些接口,而一般调试的时候都不会注意到某个类继承的接口会影响到具体调用的方法
我写了很多调试的方法,请看dotnet 代码调试方法
引用子类方法
按照这个约定,其实还可以让基类在满足一定条件的时候才能执行,这个条件需要子类定义。这个方法是上面说到的内部方法隐藏的升级,用起来将会更复杂
在基类里面判断当前类是否继承了某个接口,如果继承了,那么将会可以调用接口的方法。这个方法一般用在某个接口的声明要用到很多基类的信息才能实现,或某个接口本身不适合在外部的其他类继承,只能由子类继承
例如我定义了接口,用来判断林德熙是不是逗比的接口,而这个接口的方法实现需要依赖于基类的内容才能判断,但基类的内容是私有的,从业务上也不应该让外部方法知道
public interface ILindexiConverter
{
bool CheckLindexiIsDoubi();
}
以下是基类的定义
public class BassClass
{
protected string Name { get; } = "林德熙逗比";
public string GetPrivateString()
{
// 忽略代码
}
}
基类里面定义的 Name 属性是不能给外部类知道的,要不大家都知道我逗比,只有子类才能知道
此时基类需要依赖 ILindexiConverter 的判断才能决定是否需要做业务
public string GetPrivateString()
{
// 忽略代码
if (!lindexiConverter.CheckLindexiIsDoubi())
{
throw new NotSupportedException("这个方法除非是林德熙逗比才能使用,其他人不能使用");
}
}
然而 ILindexiConverter 接口除非是子类,其他类是无法按照预期做到的,于是在基类里面可以这样写
if (this is ILindexiConverter lindexiConverter)
{
if (!lindexiConverter.CheckLindexiIsDoubi())
{
throw new NotSupportedException("这个方法除非是林德熙逗比才能使用,其他人不能使用");
}
}
判断当前这个类是否有继承 ILindexiConverter 接口,如果有就调用方法,按照这个方式写小伙伴就更加不能简单调用这个方法
而作为逗比我将会写出下面的代码,用于调用
public class Foo2 : BassClass, ILindexiDb, IFoo, ILindexiConverter
{
public void GetString()
{
Console.WriteLine(GetPrivateString());
}
/// <inheritdoc />
public bool CheckLindexiIsDoubi()
{
return base.Name == "林德熙逗比";
}
}
我在 Foo2 里面的 CheckLindexiIsDoubi 用到基类的属性判断,同时基类因为子类继承了预期接口而能使用
这就是通过在基类里面定义好方法和定义好代码逻辑,只要子类继承接口才能实现
我搭建了自己的博客 https://blog.lindexi.com/ 欢迎大家访问,里面有很多新的博客。只有在我看到博客写成熟之后才会放在csdn或博客园,但是一旦发布了就不再更新
如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。
C# 在基类定义好方法让子类继承接口就能实现的更多相关文章
- 2019-7-29-C#-在基类定义好方法让子类继承接口就能实现
title author date CreateTime categories C# 在基类定义好方法让子类继承接口就能实现 lindexi 2019-07-29 09:57:49 +0800 201 ...
- C#中通过类来继承两个接口,父类实例化接口中的方法,子类继承父类,调用方法
实现了父类继承接口,父类实例化接口的方法,子类继承父类,子类调用父类的方法直接使用 代码如下: using System; using System.Collections.Generic; usin ...
- Kendo UI - Class 基类定义
在 kendo 中,使用原型继承机制,Class 是 Kendo 中的基类,定义了函数 extend 用来派生其它类. function Class() {} Class.extend = funct ...
- 派生类地址比基类地址少4(子类与基类指针强行转换的时候,值居然会发生变化,不知道Delphi BCB是不是也这样) good
大家对虚表并不陌生,都知道每个含有虚函数的类对象都有1个虚指针,但是在现实使用中,却总是因为这而调试半天,才发现原来是虚指针惹的祸.我这几天在调试代码时候也中招了,我的问题是这样的,如下图,CTree ...
- C++//菱形继承 //俩个派生类继承同一个基类 //又有某个类同时继承俩个派生类 //成为 菱形继承 或者 钻石 继承//+解决
1 //菱形继承 2 //俩个派生类继承同一个基类 3 //又有某个类同时继承俩个派生类 4 //成为 菱形继承 或者 钻石 继承 5 6 #include <iostream> 7 #i ...
- .NET Framework中Object基类有哪些方法?
ToString(),虚方法,任何子类可重写自定义 GetType(),非虚,返回类型名 Equals(),虚方法,默认情况下判定两个引用是否指向同一实例.(ReferenceEquals()功能相同 ...
- Java Swing类 例子代码:将子类继承JFrame 并且接口按键监听ActionLisetener (将内容直接添加到JFrame不创建Contaniner)
package rom; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import ...
- 流畅python学习笔记:第十一章:抽象基类
__getitem__实现可迭代对象.要将一个对象变成一个可迭代的对象,通常都要实现__iter__.但是如果没有__iter__的话,实现了__getitem__也可以实现迭代.我们还是用第一章扑克 ...
- 流畅的python学习笔记:第十一章:抽象基类
__getitem__实现可迭代对象.要将一个对象变成一个可迭代的对象,通常都要实现__iter__.但是如果没有__iter__的话,实现了__getitem__也可以实现迭代.我们还是用第一章扑克 ...
随机推荐
- Directx11教程(55) 建立球形和锥形物体
原文:Directx11教程(55) 建立球形和锥形物体 本教程中,我们新建2个model class,SphereModelClass以及CylinderModelClass,分别用来表示球形和锥形 ...
- iis7服务器隐藏index.php
1.安装url重写模块 32位:http://download.microsoft.com/download/4/9/C/49CD28DB-4AA6-4A51-9437-AA001221F606/re ...
- [Linux]环境配置之jdk的安装 标签: jdk服务器linux 2016-08-07 22:18 502人阅读 评论(21)
这两天服务器崩了,所以需要重新配置环境,然后从头到尾配置了一遍,现在记录总结一下自己这两天的工作,首先是jdk的配置! 很多软件,需要jdk为基础,所以第一个装的就是jdk. 第一步,拷贝文件 首先将 ...
- HZOJ trade
强烈谴责$skyh$的没$\Huge 脸$行为. 很经典的可反悔贪心,然而我一直以为是sbdp还一直想着怎么优化…… 正常的贪心肯定是不对的. 但是由于A-C=A-B+B-C, 所以用一个小根堆维护, ...
- Java面向对象----String对象的声明和创建
String a="abcd" 相等 String b="abcd" String a=new String("abcd") 不等于 ...
- spring+springMVC+Mybatis架构下采用AbstractRoutingDataSource、atomikos、JTA实现多数据源灵活切换以及分布式事务管理
背景: 1.系统采用SSM架构.需要在10多个MYSQL数据库之间进行切换并对数据进行操作,上篇博文<springMVC+Mybatis(使用AbstractRoutingDataSource实 ...
- 第十四届中北大学ACM程序设计竞赛 J.ZBT的游戏
问题描述 第14届中北大学程序设计竞赛来了,集训队新买了一大堆气球,气球一共有K种颜色(1<=K<=256),气球的颜色从1-K编号. ZBT童心未泯,他发明了一种摆放气球的游戏,规则如下 ...
- html前端登录验证
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- [C#] ServiceStack.Redis如何批量的pop数据?
要安全的批量pop数据,有两个办法: 1.用事务(不用事务的话可能导致重复读.ServiceStack的pipeline是没有自带事务的.) 2.执行lua脚本 我这里提供用事务的实现方法: publ ...
- centos 磁盘挂载
1.更改磁盘格式 fdisk -l fdisk /dev/vdb mkfs.xfs /dev/vdb1 mkfs.xfs /dev/vdb1 -f 2.查看UUID blkid 3.挂载文件夹 vim ...