c#让不同的工厂生产不同的“鸭肉”
任务目标
实现对周黑鸭工厂的产品生产统一管理,主要产品包括鸭脖和鸭翅。武汉工厂能生生产鸭脖和鸭翅,南京工厂只能生产鸭翅,长沙工厂只能生产鸭脖。
分析任务
我们需要有武汉工厂、南京工厂、长沙工厂的类,类中需要实现生产鸭肉的函数,既然都有这个生产鸭肉的函数,我们就可以用接口来限定它。
我们还需要在周黑鸭总部下达生产的命令后,各个工厂都开始生产各自的产品,那么怎么做到让这些函数同时被执行呢?这时我们可以用委托。
前置任务
掌握c#接口和委托的使用
一、接口
在C#中,接口(interface)是一种定义了一套方法和属性但不包含实现的类型。接口规定了一个类必须实现哪些方法和属性,但它不定义这些方法和属性的具体执行内容。接口是抽象类型,不能被实例化。它们通常用于定义对象之间的协议或为不同类提供一个公共的功能接口。
例如:
// 定义一个接口
public interface IAnimal
{ void Eat(); void Sleep();
} // 一个类实现该接口
public class Dog : IAnimal
{ public void Eat() { Console.WriteLine("Dog is eating.");} public void Sleep() { Console.WriteLine("Dog is sleeping."); }
}
Dog
类在继承了接口IAnimal
接口后必须对其方法进行实现。
-
定义契约和行为:
接口定义了一组方法、属性、事件或其他成员的契约,任何实现该接口的类都必须遵循这些约定。这确保了所有实现该接口的类都具有一致的行为和特征。 -
解耦和抽象:
接口允许我们将类与其具体实现分离,从而实现更高级别的抽象。这使得代码更加模块化,易于维护和扩展。通过将实现细节隐藏在接口后面,我们可以降低类之间的耦合度,提高代码的可重用性。 -
多态性支持:
通过接口,我们可以创建引用不同类型对象的变量,只要这些类型都实现了相同的接口。这使得我们可以在不修改现有代码的情况下,将不同的类互换使用。多态性不仅提高了代码的灵活性,还使得程序更加易于扩展和修改。 -
多重继承的一种形式:
虽然C#不支持类的多重继承(即一个类不能继承自多个基类),但接口允许实现多重继承的效果。一个类可以实现多个接口,从而继承多个接口中的方法、属性等成员。这有助于组合不同的功能集,实现更复杂的业务逻辑。 -
插件式架构和框架设计:
接口在构建插件式架构和框架时非常有用。通过定义一系列接口,我们可以允许第三方开发者创建自己的实现,并将其集成到我们的系统中。这种灵活性使得框架更加开放和可扩展。 -
代码清晰和可读性:
使用接口可以使代码更加清晰和易于理解。通过将相关的方法组织到接口中,我们可以更好地描述类的职责和功能。此外,接口还可以作为文档的一部分,帮助其他开发者理解如何使用我们的类和方法。 -
版本控制和兼容性:
当需要修改现有类的行为时,如果该类实现了接口,我们可以创建一个新的类来实现相同的接口,并在需要时替换旧类。这样,我们可以保持与现有代码的兼容性,同时引入新的功能或修改现有功能。
关于本题,我们可以定义一个IProductionFactory
接口类,里面设置生产方法,然后让所有的工厂类去继承这个接口,并实现其生产方法
二、委托
委托(delegate)在C#编程中是一种特殊的类型,它表示对具有特定参数列表和返回类型的方法的引用。委托的主要用途是将方法作为参数传递给其他方法,或者异步地调用方法。通过使用委托,可以实现回调函数、事件处理、异步编程等多种功能。
具体来说,委托定义了一种方法的签名,并且可以与具有相同签名的方法相关联。一旦委托与某个方法关联,委托就可以被用来调用该方法,就好像委托本身就是一个方法一样。这使得在运行时动态地改变方法的调用成为可能。
- 委托用作回调函数来使:
首先,定义一个委托类型,它接受一个整数数组和一个整数索引(用于返回最大数的位置),并返回最大数:
public delegate int FindMaxDelegate(int[] numbers, out int maxIndex);
然后,创建几个实现这个委托的方法。这些方法将按照不同的逻辑来查找最大数:
public class MaxFinder
{ // 查找数组中的最大数(线性搜索) public static int FindMaxLinear(int[] numbers, out int maxIndex) { int max = numbers[0]; maxIndex = 0; for (int i = 1; i < numbers.Length; i++) { if (numbers[i] > max) { max = numbers[i]; maxIndex = i; } } return max; } // 另一个方法可能使用更高效的算法,这里只是为了演示 // (注意:这个示例方法并没有比线性搜索更高效,只是为了演示多个实现) public static int FindMaxDummy(int[] numbers, out int maxIndex) { // 假设这里有一个更复杂的算法来找到最大数... // 但为了简单起见,我们只是返回第一个元素 maxIndex = 0; return numbers[0]; }
}
现在,你可以创建一个方法,它接受一个整数数组和一个FindMaxDelegate委托作为参数,并使用这个委托来查找最大数:
public class Program
{ static void Main(string[] args) { int[] numbers = { 1, 3, 7, 2, 9, 5 }; FindMaxDelegate findMaxDelegate = MaxFinder.FindMaxLinear; // 使用线性搜索方法 // 使用委托来查找最大数 int max = FindMaxUsingDelegate(numbers, findMaxDelegate); int maxIndex; findMaxDelegate(numbers, out maxIndex); // 也可以直接使用委托获取最大数的索引 Console.WriteLine("Max number is: " + max); Console.WriteLine("Max number index is: " + maxIndex); } static int FindMaxUsingDelegate(int[] numbers, FindMaxDelegate findMax) { int maxIndex; return findMax(numbers, out maxIndex); }
}
程序将输出:
Max number is: 9
Max number index is: 4
- 委托用于多播调用
什么是多播调用?
委托可以添加多个函数地址,当调用委托时,这些函数都会被执行
但是如果函数有返回值,那么委托只会返回最后一个被添加进委托的函数的返回值
例如我们可以实现一个计算器委托
delegate T Calculate<T>(T x,T y);
注:委托是实现成泛型模板的
建一个数学类,里面有加减两种方法:
class Math{public int add(int x, int y) { return x + y; }public int sub(int x, int y) { return x - y; }}
将add
和sub
添加进委托中,调用委托
internal class Program{static void Main(string[] args){Math math = new Math();Calculate<int> cal = math.add;cal += math.sub;Console.WriteLine(cal(1, 2).ToString());}}
通过调试可以知道,在调用委托后,add
和sub
都被执行了
但是显示在终端的只有 -1
即sub
的返回值,==因为sub
是最后被添加进委托的。
三、完成任务
有了前面这些知识,我们便可以实现生产周黑鸭的功能了。
- 定义生产接口
public interface IProductionFactory
{//其他函数...void produce();
}
- 定义工厂类,并实现生产方法
public class WuhanFactory : IProductionFactory
{public void produce(){//具体方法...Console.WriteLine("生产鸭脖和鸭翅");}
}
public class NanjingFactory : IProductionFactory
{public void produce(){//具体方法...Console.WriteLine("生产鸭翅");}
}
public class ChangshaFactory : IProductionFactory
{public void produce(){//具体方法...Console.WriteLine("生产鸭脖");}
}
- 定义委托
delegate void ProductionDelegate();
- 实例化各个工厂,并加其生产方法添加进委托,调用委托即可实现让所有工厂生产。
static void Main(string[] args){WuhanFactory factory1 = new WuhanFactory();NanjingFactory factory2 = new NanjingFactory();ChangshaFactory factory3 = new ChangshaFactory();ProductionDelegate produce = factory1.produce;produce += factory2.produce;produce += factory3.produce;produce(); }
相关文章:
c#让不同的工厂生产不同的“鸭肉”
任务目标 实现对周黑鸭工厂的产品生产统一管理,主要产品包括鸭脖和鸭翅。武汉工厂能生生产鸭脖和鸭翅,南京工厂只能生产鸭翅,长沙工厂只能生产鸭脖。 分析任务 我们需要有武汉工厂、南京工厂、长沙工厂的类,类中需要实现生产鸭…...
大数据分析与内存计算——Spark安装以及Hadoop操作——注意事项
一、Spark安装 1.相关链接 Spark安装和编程实践(Spark3.4.0)_厦大数据库实验室博客 (xmu.edu.cn) 2.安装Spark(Local模式) 按照文章中的步骤安装即可 遇到问题:xshell以及xftp不能使用 解决办法: 在…...
论文阅读RangeDet: In Defense of Range View for LiDAR-based 3D Object Detection
文章目录 RangeDet: In Defense of Range View for LiDAR-based 3D Object Detection问题笛卡尔坐标结构图Meta-Kernel Convolution RangeDet: In Defense of Range View for LiDAR-based 3D Object Detection 论文:https://arxiv.org/pdf/2103.10039.pdf 代码&…...
3D模型格式转换工具HOOPS Exchange如何将3D文件加载到PRC数据结构中?
HOOPS Exchange是一款高效的数据访问工具,专为开发人员设计,用于在不同的CAD(计算机辅助设计)系统之间进行高保真的数据转换和交换。由Tech Soft 3D公司开发,它支持广泛的CAD文件格式,包括但不限于AutoCAD的…...
c# wpf Template ContentTemplate
1.概要 1.1 定义内容的外观 2.2 要点分析 2.代码 <Window x:Class"WpfApp2.Window1"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schem…...
空和null是两回事
文章目录 前言 StringUtils1. 空(empty):字符串:集合: 2. null:引用类型变量:基本类型变量: 3. isBlank总结: 前言 StringUtils 提示:这里可以添加本文要记录…...
UNIAPP(小程序)每十个文章中间一个广告
三十秒刷新一次广告 ad-intervals"30" <template><view style"margin: 30rpx;"><view class"" v-for"(item,index) in 100"><!-- 广告 --><view style"margin-bottom: 20rpx;" v-if"(inde…...
pip包安装用国内镜像源
一:临时用国内源 可以在使用pip的时候加参数-i https://pypi.tuna.tsinghua.edu.cn/simple 例如:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyspider,这样就会从清华这边的镜像去安装pyspider库 清华:https://py…...
uniapp:小程序腾讯地图程序文件qqmap-wx-jssdk.js 文件一直找不到无法导入
先看问题: 在使用腾讯地图api时无法导入到qqmap-wx-jssdk.js文件 解决方法:1、打开qqmap-wx-jssdk.js最后一行 然后导入:这里是我的路径位置,可以根据自己的路径位置进行更改导入 最后在生命周期函数中输出: 运行效果…...
如何物理控制另一台电脑以及无网络用作副屏(现成设备和使用)
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 控制另一台电脑有很多方法&…...
Aurora8b10b(1)IP核介绍并基于IP核进行设计
文章目录 前言一、IP核设置二、基于IP核进行设计2.1、设计框图2.2、aurora_8b10b_0模块2.3、aurora_8b10b_0_CLOCK_MODULE2.4、aurora_8b10b_0_SUPPORT_RESET_LOGIC2.5、aurora8b10b_channel模块2.6、IBUFDS_GTE2模块2.7、aurora_8b10b_0_gt_common_wrapper模块2.8、aurora8b10…...
基于Springboot的美发管理系统(有报告)。Javaee项目,springboot项目。
演示视频: 基于Springboot的美发管理系统(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构&…...
最新测试技术
在软件测试领域,随着技术的不断进步和行业需求的变化,新的测试技术和方法不断涌现。以下是一些最新的测试技术,它们正在塑造着软件测试的未来: 人工智能和机器学习(AI/ML)在测试中的应用 人工智能和机器学习正在被集成到软件测试中,以提高测试的自动化水平和效率。AI可…...
【算法】初识算法
尽量不说废话 算法 一、数据结构二、排序算法三、检索算法四、字符算类型算法五、递归算法六、贪心算法七、动态规划八、归一化算法后记 我们这里指的算法,是作为程序员在计算机编程时运用到的算法。 算法是一个庞大的体系,主要包括以下内容:…...
HomeBrew 安装与应用
目录 前言一、安装 HomeBrew二、使用 HomeBrew1、使用 brew 查看已安装的软件包2、使用 brew 安装软件包3、使用 brew 升级已安装的软件包4、brew 还有哪些命令呢? 前言 在 macOS(或Linux)系统里,默认是没有软件包的管理器的&…...
JS详解-设计模式
工厂模式: 单例模式: // 1、定义一个类class SingleTon{// 2、添加私有静态属性static #instance// 3、添加静态方法static getInstance(){// 4、判断实例是否存在if(!this.#instance){// 5、实例不存在,创建实例this.#instance new Single…...
探寻马来西亚服务器托管的优势与魅力
随着全球跨境业务的不断增加,境外服务器成为越来越受欢迎的选择。在这其中,马来西亚服务器备受关注,其机房通常位于马来西亚首都吉隆坡。对于客户群体主要分布在东南亚、澳大利亚和新西兰等地区的用户来说,马来西亚服务器是一个理…...
虚幻UE5数字孪生蓝图开发教程
一、背景 这几年,智慧城市/智慧交通/智慧水利等飞速发展,骑士特意为大家做了一个这块的学习路线。 二、这是学习大纲 1.给虚幻UE5初学者准备的智慧城市/数字孪生蓝图开发教程 https://www.bilibili.com/video/BV1894y1u78G 2.UE5数字孪生蓝图开发教学…...
七、Mybatis-缓存
文章目录 缓存一级缓存二级缓存1.概念2.二级缓存开启的条件:3.使二级缓存失效的情况:4.在mapper配置文件中添加的cache标签可以设置一些属性:5.MyBatis缓存查询的顺序 缓存 一级缓存 级别为sqlSession,Mybatis默认开启一级缓存。 使一级缓存失效的四种…...
数据结构(六)——图的应用
6.4 图的应用 6.4.1 最小生成树 对于⼀个带权连通⽆向图G (V, E),⽣成树不同,每棵树的权(即树中所有边上的权值之和)也可能不同。设R为G的所有⽣成树的集合,若T为R中边的权值之和最小的生成树,则T称为G的…...
java自动化测试学习-03-06java基础之运算符
运算符 算术运算符 运算符含义举例加法,运算符两侧的值相加ab等于10-减法,运算符左侧减右侧的值a-b等于6*乘法,运算符左侧的值乘以右侧的值a*b等于16/除法,运算符左侧的值除以右侧的值a/b等于4%取余,运算符左侧的值除…...
【VASP学习】在Ubuntu系统安装vasp.5.4.4的全过程(包括VASP官方学习资料、安装过程中相关编辑器的配置、VASP的编译及VASP的测试)
在Ubuntu系统安装vasp.5.4.4的全过程 VASP的简介与相关学习资料安装前的准备工作及说明安装过程intel编译器的安装VASP的编译VASP的测试 参考来源 VASP的简介与相关学习资料 VASP(Vienna Ab initio Simulation Package)是基于第一性原理对原子尺度的材料进行模拟计算的软件。比…...
PyTorch|Dataset与DataLoader使用、构建自定义数据集
文章目录 一、Dataset与DataLoader二、自定义Dataset类(一)\_\_init\_\_函数(二)\_\_len\_\_函数(三)\_\_getitem\_\函数(四)全部代码 三、将单个样本组成minibatch(Data…...
4.6(信息差)
🌍 山西500千伏及以上输电线路工程首次采用无人机AI自主验收 🌋 中国与泰国将开展国际月球科研站等航天合作 ✨ 网页版微软 PowerPoint 新特性:可直接修剪视频 🍎 特斯拉开始在德国超级工厂生产出口到印度的右舵车 1.马斯克&…...
关于C#操作SQLite数据库的一些函数封装
主要功能:增删改查、自定义SQL执行、批量执行(事务)、防SQL注入、异常处理 1.NuGet中安装System.Data.SQLite 2.SQLiteHelper的封装: using System; using System.Collections.Generic; using System.Data.SQLite; using System.…...
LeetCode-79. 单词搜索【数组 字符串 回溯 矩阵】
LeetCode-79. 单词搜索【数组 字符串 回溯 矩阵】 题目描述:解题思路一:回溯 回溯三部曲。这里比较关键的是给board做标记,防止之后搜索时重复访问。解题思路二:回溯算法 dfs,直接看代码,很容易理解。visited哈希,防止…...
游戏引擎之高级动画技术
一、动画混合 当我们拥有各类动画素材(clips)时,要将它们融合起来成为一套完整的动画。 最经典的例子就是从走的动画自然的过渡到跑的动画。 1.1 线性插值 不同于上节课的LERP(同一个clip内不同pose之间)ÿ…...
Oracle 数据库中的全文搜索
Oracle 数据库中的全文搜索 0. 引言1. 整体流程2. 创建索引2-1. 创建一个简单的表2-2. 创建文本索引2-3. 查看创建的基础表 3. 运行查询3-1. 运行文本查询3-2. CONTAINS 运算符3-3. 混合查询3-4. OR 查询3-5. 通配符3-6. 短语搜索3-7. 模糊搜索(Fuzzy searches&…...
代码随想录阅读笔记-二叉树【二叉搜索树中的众数】
题目 给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。 假定 BST 有如下定义: 结点左子树中所含结点的值小于等于当前结点的值结点右子树中所含结点的值大于等于当前结点的…...
AcWing-游戏
1388. 游戏 - AcWing题库 所需知识:博弈论,区间dp 由于双方都采取最优的策略来取数字,所以结果为确定的,有可能会有多个不同的过程,但是我们只需要关注最终结果就行了。 方法一: 定义dp[i][j] 表示区间…...
网站建设与管理是什么工作/seo综合优化公司
近日,有报道称新出台的《银行卡收单业务管理办法》征求意见稿,明确要求“对使用个人银行结算账户作为收单结算账户的特约商户,收单机构不得开通信用卡受理功能”,这意味着,如果商户没有对公账户,POS机或不能…...
郑州个人做网站汉狮/如何做推广宣传
c语言入门C语言一经出现就以其功能丰富、表达能力强、灵活方便、应用面广等特点迅速在全世界普及和推广。C语言不但执行效率高而且可移植性好,可以用来开发应用软件、驱动、操作系统等。C语言也是其它众多高级语言的鼻祖语言,所以说学习C语言是进入编程世…...
镇江网站建设 的公司/百家联盟推广部电话多少
📖摘要 今天分享下 —— VSCode 更新失败解决 的一些基本知识,欢迎关注! 我的VS Code 是1.3.0版本,并且是把同事那已经安装好的Vs Code文件夹拷贝到本机,直接使用的,以此为背景。 🌂分享 今日 &…...
网站建设与管理总结报告/如何优化关键词
刷题主页 在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为“根”。 除了“根”之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地…...
wordpress创建文档系统/国内新闻最近新闻今天
一、卸载掉原有mysql [rootxiaoluo ~]# rpm -qa | grep mysql // 这个命令就会查看该操作系统上是否已经安装了mysql数据库 [rootxiaoluo ~]# rpm -e mysql // 普通删除模式 [rootxiaoluo ~]# rpm -e --nodeps mysql // 强力删除模式,如果使用上面命令删除…...
信息技术制作网站/广东免费网络推广软件
克隆节点有深度克隆和浅克隆,它是用布尔类型来判断的,true代表深克隆,false代表浅克隆。深克隆会把标签,内容都克隆,浅克隆只会克隆标签。 创建动态元素有三种方式,分别为:document.write()&…...