C#中接口的显式实现与隐式实现及其相关应用案例

C#中接口的显式实现与隐式实现

最近在学习演化一款游戏项目框架时候,框架作者巧妙使用接口中方法的显式实现来变相对接口中方法进行“密封”,增加实现接口的类访问方法的“成本”。

接口的显式实现和隐式实现:

先定义一个接口,接口中有这两个方法。

 public interface ICanSingSong{void SingJayChow();void SingOther();}

接下来我们让InterfaceDesignExample 继承该接口。使用常用的隐式实现方法来实现SingJayChow方法,在Start函数中直接可以调用,而使用显式实现的接口方法SingOther,则需要将类的实力转换为接口类型才可以调用。

这样相当于告诉类,ICanSingSong.SingOther()样式就是表明SIngOther是属于ICanSingSong接口中的“私有方法”。调用时候先要将类类型转换为接口。

 public class InterfaceDesignExample : MonoBehaviour,ICanSingSong{void Start(){//接口的隐式实现 可以直接调用SingJayChow();//显示调用则需要 准换成接口 调用//this.SingOther();   (this as ICanSingSong).SingOther();}/// <summary>/// 接口的隐式实现/// </summary>public void SingJayChow(){Debug.Log("你说家是唯一的城堡,随着稻香一路奔跑~");}/// <summary>/// 接口的显式实现/// </summary>void ICanSingSong.SingOther(){ Debug.Log("lalalalalalallalaal!");}}

image

我们这样做的目的之一就是为了增加类对接口中的一些方法的调用成本,和使用“private”修饰有类似效果,降低对方法乱用的可能。

接口-抽象类-子类 使用显式实现接口方法

同样,我们先声明一个接口:

//接口 Application
public interface IApplication
{void Start();void Update();void Destroy();void Test();
}

抽象类继承该接口,并对生命周期函数进行显式实现,而供子类继承实现的方法为OnXXX

//抽象类
public abstract class Application : IApplication
{//不希望子类去访问实现接口的方法//使用显式调用void IApplication.Start(){OnStart();}void IApplication.Update(){OnUpdate();}void IApplication.Destroy(){OnDestroy();}public void Test(){Debug.Log("我是测试方法,隐式实现接口的方法,子类可以轻松访问我");}//希望子类的实现的方法public abstract void OnStart();public abstract void OnUpdate();public abstract void OnDestroy();
}

继承抽象类的子类对生命周期函数进行实现:

 //子类
public class SubApplication : Application
{public override void OnStart(){Test();//Start(); 情况会发生递归调用 造成堆栈溢出 而此方法使用现实实现 所以在子类中无法访问 避免情况发生Debug.Log("OnStart");}public override void OnUpdate(){Debug.Log("OnUpdate");}public override void OnDestroy(){Debug.Log("OnDestroy");}
}

最后我们调用函数:

//测试调用
//通过接口调用 显示实现的方法
IApplication application = new SubApplication();application.Start();
application.Update();
application.Destroy();//通过类 无法调用显示实现的方法 只能访问使用OnXXXX方法
Application application2 = new SubApplication();
application2.OnStart();
application2.OnUpdate();
application2.OnDestroy();

image

这样我们可以体会到接口作为高抽象层的存在,可以调用子类具体实现的生命周期函数,而子类却无法访问显示实现的接口中“私有”的生命周期函数。

接口--子接口--静态类拓展 实现对接口函数的访问修饰

咳咳~故事开始!

作为一个资深Jay迷,我同样认识一个自称曲库的小精灵【SongLibrary】,它最拿手的三首歌曲是晴天、彩虹和说好不哭.

 //曲库public class SongLibrary{public void SingSunny(){Debug.Log("晴天:刮风这天,我试着握你的手~");}//彩虹public void SingRainbow(){Debug.Log("彩虹:你要离开,我知道很简单~");}public void SingNoCry(){Debug.Log("说好不哭:说好不哭让我走~");}
}

这个小曲库精灵居住在抽象出的留声机中,我可以通过留声机来和它交流播放对应的歌曲。

public interface ISingAllSong
{SongLibrary songLibrary { get; }
}

留声机上有三个按钮,对应播放歌曲,

播放晴天的按钮功能:

抽象出子接口来继承曲库接口,通过静态类拓展来调用曲库中对应方法播放歌曲。

public interface ISingSunny : ISingAllSong
{}//静态类拓展
public static class SingSunnyExtensions
{public static void SingSunny(this ISingSunny self){self.songLibrary.SingSunny();}
}

同样的方式,两个子接口。两个继承子接口的静态类负责调用曲库中的方法:

    //彩虹public interface ISingRainbow : ISingAllSong{}//静态类拓展public static class SingRainbowExtensions{public static void SingRainbow(this ISingRainbow self){self.songLibrary.SingRainbow();}}//说好不哭public interface ISingNoCry : ISingAllSong{}//静态类拓展public static class SingNoCryExtensions{public static void SingNoCry(this ISingNoCry self){self.songLibrary.SingNoCry();}}

这样我们使用三个静态类来调用留声机【interface】中居住的精灵【class】的方法,实现三个按钮功能。

当我想听歌时候,我只需要按照我的需求,搭配继承对应的子接口即可播放对应的歌曲,不用怕我按下去的是晴天歌曲播放按钮而短路到播放其它的歌曲曲目。

这样保证,拿到对应的子按钮,只能播放对应的歌曲,保证曲目播放的有序性。

public class InterfaceRuleExample : MonoBehaviour
{public class OnlySingSunny : ISingSunny{SongLibrary ISingAllSong.songLibrary { get; } = new SongLibrary();}public class OnlySingRainbowNoCry : ISingRainbow,ISingNoCry{SongLibrary ISingAllSong.songLibrary { get; } = new SongLibrary();}void Start(){var onlySingSunny = new OnlySingSunny();onlySingSunny.SingSunny();//不能访问//onlySingSunny.SingRainbow()//onlySingSunny.SingNoCry();var SingRainbowNoCry = new OnlySingRainbowNoCry();SingRainbowNoCry.SingRainbow();SingRainbowNoCry.SingNoCry();//无法访问//SingRainbowNoCry.SingSUnny();}
}

image

总结一下:

使用显示实现方式来对接口中方法进行实现,子类是无法直接调用的,需要将类转换为接口类型才可以调用。

同时如果接口中的方法不想让子类直接调用,可以让抽象类继承接口原生方法,在抽象类中进行方法声明供子类调用,避免子类对抽象层的直接交互。同时,使用静态类拓展来限制子接口对父接口中存在函数方法的访问,保证类对所需方法的规范使用。

也就是说,尽可能不让表层具象的类轻松的访问到抽象层的其它不需要的功能,即类需要什么就继承对应的子接口,实现对应功能即可,多余的功能不要访问。

文章转载自:畅知

原文链接:https://www.cnblogs.com/TonyCode/p/18223431

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/20192.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

dolphinscheduler docker部署海豚mysql版本,docker重新封装正在运行服务为镜像

1.官方文档&#xff1a; https://dolphinscheduler.apache.org/zh-cn/docs/3.2.1/guide/installation/standalone#%E9%85%8D%E7%BD%AE%E6%95%B0%E6%8D%AE%E5%BA%93 2.github: dolphinscheduler/docs/docs/zh/guide/howto/datasource-setting.md at 3.2.1-release apache/do…

对于vsc中的vue命令 vue.json

打开vsc 然后在左下角有一个设置 2.点击用户代码片段 3.输入 vue.json回车 将此代码粘贴 &#xff08;我的不一定都适合&#xff09; { "vue2 template": { "prefix": "v2", "body": [ "<template>", " <…

探索Expect Python用法:深入解析与实战挑战

探索Expect Python用法&#xff1a;深入解析与实战挑战 在自动化和脚本编写领域&#xff0c;Expect Python已经成为了一种强大的工具组合。它结合了Expect的交互式会话处理能力和Python的编程灵活性&#xff0c;为开发者提供了一种全新的方式来处理复杂的自动化任务。然而&…

重构与优化-组织函数(1)

1. Extract Method "Extract Method"(提取方法)是软件工程中的一项基础重构技术,用于改进代码结构、增强代码的可读性和可维护性。此技术的核心思想是识别代码中可复用或者具有独立逻辑责任的部分,并将其抽离出来形成一个新的方法。以下是详细的步骤、原因、好处…

Ubuntu中PDF阅读器和编辑器

1. 福昕PDF编辑器 1.1. 下载地址 PDF阅读器下载_PDF编辑器下载_PDF软件官方下载_福昕软件官网 1.2. 安装 sudo dpkg -i signed_com.foxit.foxitpdfeditor_xxx_amd64_UOS.deb 2. WPS DPF 2.1. 下载地址 WPS Office 2019 for Linux-支持多版本下载_WPS官方网站 2.2. 使用 …

基于ES安装IK分词插件

前言 IK分词器插件是为Elasticsearch设计的中文分词插件&#xff0c;由Elasticsearch的官方团队之外的开发者medcl开发。它主要针对中文文本的分词需求&#xff0c;提供了较为准确的中文分词能力。以下是IK分词器插件的一些特点&#xff1a; 智能分词&#xff1a;IK分词器采用基…

如何 实现PHP和java 的 jwt token互通

其实最简单的问题就是 你的拓展包 用错了 PHP使用 composer require firebase/php-jwt java 需要引入 <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.…

每天学点小知识:WSL安装Ubuntu 22.04 LTS

前言 本章教会你在不使用虚拟机下使用linux&#xff0c;但是这里建议还是使用虚拟机&#xff0c;或者装一双系统&#xff0c;wsl使用linux还是有很多问题的。 1. 简介WSL WSL&#xff08;Windows Subsystem for Linux&#xff09;是微软为Windows 10及以上版本开发的一项功能…

解释Servlet的作用和生命周期

Servlet 是 Java Web 技术中的关键组件&#xff0c;用于处理客户端发送的请求并生成响应。Servlet 是运行在 Web 服务器或应用服务器上的 Java 程序&#xff0c;它扩展了特定的 Java 接口&#xff0c;以便被服务器加载和执行。下面是 Servlet 的作用和生命周期的详细解释&#…

[AIGC] Java常用的JSON库及简单示例

Java常用的JSON库及简单示例 在Java的世界里&#xff0c;JSON库广泛用于日常开发工作&#xff0c;本文将介绍几个常用的JSON库并配以简单的示例代码。 1. Gson Gson是Google提供的一个用来在Java对象和JSON数据之间进行转换的Java库。 它有一定的学习曲线&#xff0c;但一旦熟…

rust变量遮蔽(variable shadow)不影响其正常析构行为和顺序

上代码&#xff1a; use std::ops::Drop;struct D(i32);impl Drop for D {fn drop(&mut self){println!("destruct {}", self.0);} }fn main() {let _x D(1);let _x D(2); //_x被遮蔽了(variable shadow here)println!("-----------"); }//运行程序…

SQL性能优化-该如何下手

SQL性能优化是数据库管理中非常重要的一环,它直接影响到数据库查询的响应时间和系统的整体性能。以下是一些关键的SQL性能优化方法,按照不同的方面进行分类和归纳: 一、SQL语句优化 **避免使用SELECT ***:尽量指定需要查询的具体字段,而不是使用SELECT *选择所有字段。这…

Redis用GEO实现附近的人功能

文章目录 ☃️概述☃️命令演示☃️API将数据库表中的数据导入到redis中去☃️实现附近功能 ☃️概述 GEO就是Geolocation的简写形式&#xff0c;代表地理坐标。Redis在3.2版本中加入了对GEO的支持&#xff0c;允许存储地理坐标信息&#xff0c;帮助我们根据经纬度来检索数据。…

淘宝镜像的https证书过期

错误原因&#xff1a; 淘宝镜像过期 早在 2021 年&#xff0c;淘宝就发文称&#xff0c;npm 淘宝镜像已经从 http://registry.npm.taobao.org 切换到了 http://registry.npmmirror.com。旧域名也将于 2022 年 5 月 31 日停止服务&#xff08;直到 HTTPS 证书到期才真正不能用了…

【面试常见问题】深拷贝与浅拷贝

目录 一、浅拷贝基础 定义与原理 面试知识点扩展 代码示例 使用 Object.assign() 展开运算符 ... 二、深拷贝详解 定义与重要性 面试技巧 代码示例 手动递归实现 使用JSON方法&#xff08;简单情况&#xff09; 使用第三方库lodash 三、深拷贝与浅拷贝的选择依据…

Unity学习笔记---音视频播放

音频 Audiolistener组件 AudioListener组件是音频监听器&#xff0c;将组件挂在角色或camera上面&#xff0c;每个场景中最多只有一个AudioListener组件。 AudioSource组件 AudioSource组件是音源&#xff0c;用来播放音频AudioClip.将他挂在产生声音的物体上&#xff0c;可…

筛斗数据提取技术在企业成本预测中的应用

在当今的商业环境中&#xff0c;准确的成本预测对于企业的财务健康和战略规划至关重要。随着大数据和人工智能技术的飞速发展&#xff0c;数据提取技术已经成为企业进行成本预测的强大工具。本文将探讨数据提取技术如何帮助企业进行成本预测&#xff0c;并分析其对企业决策过程…

C++ 课堂实验 编写一个能判断数字大小的小程序

本关任务&#xff1a;编写一个能判断数字大小的小程序。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;1.基本输入输出&#xff0c;2.简单条件判断语句。 编程要求 问题&#xff1a;输入2个整数&#xff0c;再进行判断输出大的数。 效果如下&#xff1a; 输入&…

基于stm32的智能家居系统

目录 1.课题研究目的和内容 1.1 课题研究目的 1.2 课题研究内容 2.系统总体方案设计及功能模块介绍 2.1 总体方案设计 2.2 DHT11模块介绍 2.3 TFTLCD显示功能模块介绍 2.4 ESP8266WIFI模块介绍 2.5 MQ-135 空气质量模块介绍 2.6 步进电机模块介绍 2.…

划分字母区间 - LeetCode 热题 80

大家好&#xff01;我是曾续缘&#x1f916; 今天是《LeetCode 热题 100》系列 发车第 80 天 贪心算法第 4 题 ❤️点赞 &#x1f44d; 收藏 ⭐再看&#xff0c;养成习惯 划分字母区间 给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段&#xff0c;同一字母最多出现…