当前位置: 首页 > news >正文

C# 中的接口:定义行为契约与实现多态性

C#中的接口(Interfaces)。接口是C#中一个非常重要的特性,它允许定义类型的行为契约,而不指定具体实现。通过接口,可以实现多态性、代码的灵活性和可扩展性。以下是一篇关于C#中接口的文章。


引言

接口(Interfaces)是 C# 中一个非常重要的特性,它允许定义类型的行为契约,而不指定具体实现。通过接口,可以实现多态性、代码的灵活性和可扩展性。本文将详细介绍C#中的接口,包括其基本概念、使用方法和应用场景。

接口的基本概念

什么是接口?

接口是一种引用类型,它定义了一组相关的方法、属性、事件或索引器,但不提供具体的实现。接口用于定义行为契约,任何实现了该接口的类都必须提供这些成员的具体实现。

接口的优势

  • 多态性:接口允许不同类型的对象以统一的方式进行处理。
  • 灵活性:接口可以被多个类实现,从而提高代码的灵活性。
  • 可扩展性:接口可以继承其他接口,从而扩展行为契约。

定义接口

接口的基本结构

定义接口时,使用 interface 关键字,并在接口中声明成员。

public interface IAnimal
{void MakeSound();
}

实现接口

实现接口时,需要为接口中声明的所有成员提供具体的实现。

public class Dog : IAnimal
{public void MakeSound(){Console.WriteLine("Woof!");}
}public class Cat : IAnimal
{public void MakeSound(){Console.WriteLine("Meow!");}
}

使用接口

多态性

接口使得不同类型的对象可以通过共同的接口进行操作,体现了多态性的特点。

public class Program
{public static void Main(){List<IAnimal> animals = new List<IAnimal>{new Dog(),new Cat()};foreach (IAnimal animal in animals){animal.MakeSound();}}
}

显式接口实现

显式接口实现是指在类中实现接口成员时,使用接口名称限定成员名。这样可以在特定情况下调用接口成员。

public class Animal : IAnimal
{void IAnimal.MakeSound(){Console.WriteLine("This is an explicit implementation.");}public void MakeSound(){Console.WriteLine("This is a public implementation.");}
}public class Program
{public static void Main(){Animal animal = new Animal();animal.MakeSound(); // 调用公共实现IAnimal iAnimal = animal;iAnimal.MakeSound(); // 调用显式实现}
}

接口的继承

接口可以继承其他接口,从而扩展行为契约。

public interface IMammal : IAnimal
{void Eat();
}public class Human : IMammal
{public void MakeSound(){Console.WriteLine("Hello!");}public void Eat(){Console.WriteLine("Eating...");}
}

接口与抽象类的区别

  • 接口:只定义行为契约,不提供具体实现;可以由多个类实现。
  • 抽象类:可以定义部分实现,并且可以包含字段、属性等成员;只能被单个类继承。

接口的应用场景

插件系统

接口常用于插件系统,使得不同的插件可以通过相同的接口进行交互。

public interface IPlugin
{void Execute();
}public class Plugin1 : IPlugin
{public void Execute(){Console.WriteLine("Executing Plugin 1");}
}public class Plugin2 : IPlugin
{public void Execute(){Console.WriteLine("Executing Plugin 2");}
}public class PluginManager
{private List<IPlugin> plugins = new List<IPlugin>();public void AddPlugin(IPlugin plugin){plugins.Add(plugin);}public void RunPlugins(){foreach (IPlugin plugin in plugins){plugin.Execute();}}
}public class Program
{public static void Main(){PluginManager manager = new PluginManager();manager.AddPlugin(new Plugin1());manager.AddPlugin(new Plugin2());manager.RunPlugins();}
}

数据访问层

接口常用于数据访问层,使得不同的数据存储方式可以通过相同的接口进行操作。

public interface IDataAccess
{void Save<T>(T entity);T Load<T>(int id);
}public class SqlDataAccess : IDataAccess
{public void Save<T>(T entity){Console.WriteLine($"Saving {typeof(T).Name} to SQL database.");}public T Load<T>(int id){Console.WriteLine($"Loading {typeof(T).Name} from SQL database.");return default(T);}
}public class MongoDataAccess : IDataAccess
{public void Save<T>(T entity){Console.WriteLine($"Saving {typeof(T).Name} to MongoDB.");}public T Load<T>(int id){Console.WriteLine($"Loading {typeof(T).Name} from MongoDB.");return default(T);}
}public class Program
{public static void Main(){IDataAccess dataAccess = new SqlDataAccess();dataAccess.Save(new object());var loadedObject = dataAccess.Load<object>(1);dataAccess = new MongoDataAccess();dataAccess.Save(new object());loadedObject = dataAccess.Load<object>(1);}
}

结论

通过使用接口,可以定义行为契约,实现多态性、代码的灵活性和可扩展性。接口不仅在插件系统和数据访问层等场景中有广泛的应用,还在面向对象编程中扮演着重要角色。希望本文能够帮助你更好地理解和应用C#中的接口技术。如果你有任何疑问或需要进一步的信息,请随时留言讨论!


希望这篇关于C#中接口的文章对你有所帮助。如果有任何问题或需要进一步的信息,请随时告诉我!

相关文章:

C# 中的接口:定义行为契约与实现多态性

C#中的接口&#xff08;Interfaces&#xff09;。接口是C#中一个非常重要的特性&#xff0c;它允许定义类型的行为契约&#xff0c;而不指定具体实现。通过接口&#xff0c;可以实现多态性、代码的灵活性和可扩展性。以下是一篇关于C#中接口的文章。 引言 接口&#xff08;Int…...

Redis的基础知识·

Redis是一个基于内存的key-value的结构数据库 基于内存存储 读写性能高适合存储热点数据&#xff08;热点商品 咨询 新闻&#xff09; 开启Redis 首先输入命令 redis-server.exe redis.windows.conf 然后重新打开命令行窗口 输入命令 redis-cli.exe 输入密码 …...

qt QProxyStyle详解

1、概述 QProxyStyle是Qt框架中QStyle类的一个子类&#xff0c;它提供了一种代理机制&#xff0c;允许开发者在不直接修改现有样式&#xff08;QStyle&#xff09;实现的情况下&#xff0c;对样式行为进行定制或扩展。通过继承QProxyStyle&#xff0c;开发者可以重写其虚方法&…...

AWS CLI 操作指南

AWS CLI 操作指南 世间本来就存在许多乐境&#xff0c;只是现代人为世间所累而未能予以关注&#xff0c;也就失去了许多体验乐境的机会。比如&#xff0c;忙里偷闲看云&#xff0c;以悠闲的心看悠闲的云&#xff0c;便是一种极妙的乐境。 本文将介绍如何配置 AWS CLI&#xff0…...

海盗王用golang重写的AccountServer功能

自从用golang重写了海盗王的网关gateserver以来&#xff0c;一直想把accountserver也重写了&#xff0c;但是一直没有进行。 趁上次刚写好那个golang版的更新器&#xff0c;还有些熟悉&#xff0c;于是把原来AccountServer的C代码重写读了个大概。它原版的写得太过于复杂&#…...

如何保证spring boot应用程序的安全性?

保证Spring Boot应用程序的安全性是至关重要的&#xff0c;以下是小编为大家列举的一些关键措施和最佳实践&#xff1a; 文章目录 1. 使用Spring Security2. 安全配置3. 数据加密4. 凭证管理5. 输入验证6. 异常处理7. 定期更新依赖8. 日志监控9. 审计日志10. 安全培训 1. 使用S…...

力扣 岛屿数量-200

岛屿数量-200 class Solution {//深度优先搜索 dfs public:int vis[300][300] {0};//用于标记的数组&#xff0c;标记是否遍历过int cnt 0;//岛屿计数//上下左右的移动方向数组int dx[4]{-1,1,0,0};int dy[4]{0,0,-1,1};//深度优先搜索void dfs(vector<vector<char>…...

极狐GitLab 17.6 正式发布几十项与 DevSecOps 相关的功能【三】

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 学习极狐GitLab 的相关资料&#xff1a; 极狐GitLab 官网极狐…...

十二、正则表达式、元字符、替换修饰符、手势和对话框插件、字符串截取

1. 正则表达式 1.1 基本使用 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title&g…...

【信息系统项目管理师】第3章:信息系统治理 考点梳理

文章目录 3.1 IT 治理3.1.1 IT治理基础3.1.2 IT治理体系3.1.3 IT治理任务3.1.4 IT治理方法与标准 3.2 IT 审计3.2.1 IT审计基础3.2.2 审计方法与技术3.2.3 审计流程3.2.4 审计内容 3.1 IT 治理 IT治理起到重要的统筹、评估、指导和监督作用。 信息技术审计(IT审计)作为与IT治…...

实现对图片或者视频增加隐藏水印和提取水印

好久好久没有写博客了&#xff0c;最近看见一个很有意思的文章&#xff1a;小心你的电脑被窃听&#xff0c;就是说在一些公司&#xff0c;截图都会存在水印&#xff0c;方便溯源&#xff0c;然后出于技术的好奇&#xff0c;我在github上搜了一下&#xff0c;还真有相关的github…...

uniapp配置全局消息提醒

1.H5使用根标签插入dom的方式实现。 2.app端使用plus.nativeObj.View的方式绘制实现 H5端app端 H5端 创建组件orderAlert.vue <template><div class"view"><div class"content" v-if"visible"><div class"message&q…...

卸载snap docker一直卡住:Save data of snap “docker“ in automatic snapshot set #3

在卸载 Snap 安装的 Docker 时卡住&#xff0c;通常是因为 Snap 在执行卸载时会先尝试保存一些快照&#xff08;自动或手动创建的&#xff09;&#xff0c;并且该过程可能因某些原因而卡住。为了解决这个问题&#xff0c;你可以按照以下步骤强制删除 Snap 安装的 Docker&#x…...

python学习——字典元素的访问和遍历

在Python中&#xff0c;访问和遍历字典元素的方法如下&#xff1a; 文章目录 访问字典元素1. 使用键来访问值2. 使用 get() 方法 遍历字典元素1. 遍历字典的键2. 遍历字典的值3. 遍历字典的键和值4. 使用列表推导式来创建新的列表 实操 访问字典元素 1. 使用键来访问值 # 创…...

数据结构基础之《(9)—归并排序》

一、什么是归并排序 1、整体是递归&#xff0c;左边排好序右边排好序merge让整体有序 2、让其整体有序的过程里用了排外序方法 3、利用master公式来求解时间复杂度 4、当然可以用非递归实现 二、归并排序说明 1、首先有一个f函数 void f(arr, L, R) 说明&#xff1a;在arr上…...

【深度学习】各种卷积—卷积、反卷积、空洞卷积、可分离卷积、分组卷积

在全连接神经网络中&#xff0c;每个神经元都和上一层的所有神经元彼此连接&#xff0c;这会导致网络的参数量非常大&#xff0c;难以实现复杂数据的处理。为了改善这种情况&#xff0c;卷积神经网络应运而生。 一、卷积 在信号处理中&#xff0c;卷积被定义为一个函数经过翻转…...

远程视频验证如何改变商业安全

如今&#xff0c;商业企业面临着无数的安全挑战。尽管企业的形态和规模各不相同——从餐厅、店面和办公楼到工业地产和购物中心——但诸如入室盗窃、盗窃、破坏和人身攻击等威胁让安全主管时刻保持警惕。 虽然传统的监控摄像头网络帮助组织扩大了其态势感知能力&#xff0c;但…...

电脑启动需要经历哪些过程?

传统BIOS启动流程 1. BIOS BIOS 启动&#xff0c;BIOS程序是烧进主板自带的ROM里的&#xff0c;所以无硬盘也可以启动。BIOS先进行自检&#xff0c;检查内存、显卡、磁盘等关键设备是否存在功能异常&#xff0c;会有蜂鸣器汇报错误&#xff0c;无错误自检飞快结束。 硬件自检…...

纯Go语言开发人脸检测、瞳孔/眼睛定位与面部特征检测插件-助力GoFly快速开发框架

前言​ 开发纯go插件的原因是因为目前 Go 生态系统中几乎所有现有的人脸检测解决方案都是纯粹绑定到一些 C/C 库&#xff0c;如 ​​OpenCV​​ 或 ​​​dlib​​​&#xff0c;但通过 ​​​cgo​​​ 调用 C 程序会引入巨大的延迟&#xff0c;并在性能方面产生显著的权衡。…...

postman使用正则表达式提取数据实战篇!

之前篇章中postman多接口关联使用的是通过JSON提取器的方式进行提取。 除了JSON提取器提取数据外还可通过另一种方式——正则表达式来提取数据。 1、使用正则表达式提取器实现接口关联&#xff0c;match匹配 正则匹配表达式将需要提取的字段key:value都放入表达式中&#xff…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...