设计理念中——抽象与接口和用(C#)

news2024/9/24 13:18:13

前言

在程序设计中,使用抽象类还是用接口应该是一个需要考虑的场景,有时我们感觉这两者并没有太大的区别,有时又有很大区别。这里是一些说明和示例。

一、抽象类和接口


1、相同点:

1)都可以被继承

2)都不能被实例化

3)都可以包含方法声明

4)派生类必须实现未实现的方法


2、区别

1)抽象基类可以定义字段、属性、方法实现。接口只能定义属性、索引器、事件、和方法声明,不能包含字段。
2)抽象类是一个不完整的类,需要进一步细化,而接口是一个行为规范。微软的自定义接口总是后带able字段,证明其是表述一类“我能做……”
3)接口可以被多重实现,抽象类只能被单一继承
4)抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中。
5)抽象类是从一系列相关对象中抽象出来的概念,因此反映的是事物的内部共性;接口是为了满足外部调用定义的一个功能约定,因此反映的是事物的外部特性
6)接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法。
7)接口可以用于支持回调,而继承并不具备这个特点。
8)抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的。
9)如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为 抽象方法而不必实现,而在抽象类的子类中实现接口中方法。

3、使用规则

1)抽象类主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能。
2)如果要设计大的功能单元,则使用抽象类;如果要设计小而简练的功能块,则使用接口。
3)如果预计要创建组件的多个版本,则创建抽象类。接口一旦创建就不能更改。如果需要接口的新版本,必须创建一个全新的接口。
4)如果创建的功能将在大范围的全异对象间使用,则使用接口;如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。
5)分析对象,提炼内部共性形成抽象类,用心表示对象本质,即“是什么”。为外部提供调用或功能需要扩充时优先使用接口。
6)好的接口定义应该是具有专一功能性的,而不是多功能的,否则生成接口污染。如果一个类只是实现了这个接口中一个功能,而不得不去实现接口中的其他方法,就叫接口在污染。
7)尽量避免使用继承来实现组建功能,而是使用黑箱复用,即对象组合。因为继承的层次增多,造成最直接的后果就是当调用这个类群中某一类,就必须把他们全部加载到栈中!后果可想而知
(结合堆栈原理理解)。微软在构建一个类时,很多时候用到了对象组合的方法。

二、代码示例

public delegate void EnableHadler(object sender, EventArgs e);
        public delegate void CPU_CallBack(CPU cpu);

        public interface I9_Cpu_Interface
        {
            void FCLGA1700();
            bool Enable
            {
                get;
            }
            int this[int index]
            {
                get;
            }
            event EventHandler EnableFCLGA1700;
        }
        public abstract class CPU : I9_Cpu_Interface
        {
            public event EventHandler EnableFCLGA1700;
            int[] pins;
            string _name;
            double _frequency;
            int _kernel;
            int _pinNum;
            bool _isEnableFCLGA1700;

            public CPU(string name, double frequency, int kernel, int pin, bool isEnableFCLGA1700)
            {
                _name = name;
                _frequency = frequency;
                _kernel = kernel;
                _pinNum = pin;
                pins = new int[pin];
                _isEnableFCLGA1700 = isEnableFCLGA1700;
                EnableFCLGA1700 += new EventHandler(CPU_EnableFCLGA1700);
            }

            void CPU_EnableFCLGA1700(object sender, EventArgs e)
            {
                Console.WriteLine("我支持FCLGA1700");
            }

            public string Name => _name;
            public double Frequency => _frequency;
            public int Kernel => _kernel;
            public int PinNum => _pinNum;

            protected abstract void ProwerOn();
            protected abstract void SelfCheck();
            public override string ToString()
            {
                return string.Format("我是{0} CPU,我的主频是{1:0.0},我有{2}个内核,我的引脚有{3}个", _name, _frequency, _kernel, _pinNum);
            }
            public int this[int index]
            {
                get
                {
                    if (index<pins.Length)
                    {
                        return pins[index];
                    }
                    return -1;
                }
            }

            public bool Enable {
                get
                {
                    if (_isEnableFCLGA1700)
                    {
                        EnableFCLGA1700.Invoke(this, null);
                    }
                    return _isEnableFCLGA1700;
                }
            }

            public void FCLGA1700()
            {
                Console.WriteLine("1、处理器最高可达二十四核。");
                Console.WriteLine("2、支持双通道DDR4或DDR5内存。");
                Console.WriteLine("3、支持PCI-E 5.0规范。");
                Console.WriteLine("4、芯片组使用单芯片设计,支持两个SATA 3Gbps和多达十个SATA/SAS 6Gbps接口。");


            }
        }

        public class i7_13900K : CPU
        {
            public i7_13900K()
                :base("i7_13900K", 5.8,16,1700,true)
            {
                Console.WriteLine(base.ToString());
                ProwerOn();

                SelfCheck();

            }
            protected override void ProwerOn()
            {
                Console.WriteLine("i7_13900K 上电完成");
            }

            protected override void SelfCheck()
            {
                Console.WriteLine("i7_13900K 自检完成");
            }
        }

         public class i7_14900K : CPU
        {
            public i7_14900K()
                : base("i7- 14900K", 6.0, 16, 1700, true)
            {
                Console.WriteLine(base.ToString());
                ProwerOn();

                SelfCheck();

            }
            protected override void ProwerOn()
            {
                Console.WriteLine("i7-14900K 上电完成");
            }

            protected override void SelfCheck()
            {
                Console.WriteLine("i7-14900K 自检完成");
            }
        }

        public class CreateCPU
        {
            CPU_CallBack callBack;
            CPU _cpu = null;
            public CreateCPU(CPU cpu)
            {
                _cpu = cpu;
                callBack = new CPU_CallBack(cpu_call_balc);
            }

            void cpu_call_balc(CPU u)
            {
                if (u.Enable)
                {
                    u.FCLGA1700();
                }
            }
            public void ShowMessage()
            {
                callBack.Invoke(_cpu);
            }
        }


        static void Main(string[] args)
        {
            CreateCPU createI7_13900k = new CreateCPU(new i7_13900K());
            createI7_13900k.ShowMessage();

            Console.WriteLine();

            CreateCPU createI7_14900k = new CreateCPU(new i7_14900K());
            createI7_14900k.ShowMessage();
            Console.Read();
        }

三、效果

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

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

相关文章

paddleSeg项目实战

问题1&#xff1a;cmake 编译报错 解决办法&#xff1a;添加一条语句 set(DEMO_NAME "test_seg") #这里的test_seg就是src里的文件名问题2&#xff1a; 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 LNK2038 检测到“RuntimeLibrary”的不匹配项: 值“MT_Stat…

汽车EDI中的常见术语以及流程详解

汽车EDI常见术语 EDI —— 电子数据交换3PL&#xff08;第三方物流&#xff09; —— 外包仓库/运输供应商。 一般用于售后市场&#xff0c;但偶尔也用于原始设备制造商。也可由原始设备制造商和售后市场公司用来分销产品。Aftermarket&#xff08;后市场&#xff09; —— 经…

详细阐述大模型微调过程、方法、案例

大模型微调 大模型微调&#xff08;Fine-tuning&#xff09;的定义是&#xff1a;在已经预训练好的大型深度学习模型基础上&#xff0c;使用新的、特定任务相关的数据集对模型进行进一步训练的过程。这种微调技术的主要目的是使模型能够适应新的、具体的任务或领域&#xff0c…

透明屏幕方案介绍

透明屏幕方案主要涉及透明显示屏的技术原理、应用场景、优势以及未来发展趋势等方面。以下是对透明屏幕方案的详细介绍&#xff1a; 一、技术原理 透明屏幕&#xff0c;特别是透明LED显示屏和透明OLED显示屏&#xff0c;采用了先进的技术原理来实现其独特的显示效果。 透明LED显…

牛客 KY11.二叉树遍历

牛客 KY11.二叉树遍历 思路&#xff1a; 我们接收字符串以后&#xff0c;创建一个二叉树结构体&#xff0c;然后就可以开始建立树&#xff0c;如果是字符就malloc新的结点去存储&#xff0c;是**#就返回空**&#xff0c;最后用递归以根左右的顺序创建结点。树建立完成后&#x…

Linux中防火墙实战之Web服务器和ssh远程服务配置指南

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f427;Linux基础知识(初学)&#xff1a;点击&#xff01; &#x1f427;Linux高级管理防护和群集专栏&#xff1a;点击&#xff01; &#x1f510;Linux中firewalld防火墙&#xff1a;点击&#xff01; ⏰️创作…

螺钉柱的设计

如果螺钉柱参数设置不合理&#xff0c;可能导致螺钉柱滑牙、爆裂、断裂、螺丝断裂、螺钉头磨损、螺钉攻入费力等问题 具体参数可以参照下表 螺丝柱设计尺寸&#xff1a; 螺丝柱设计要点&#xff1a; 频繁拆卸的注意事项&#xff1a; 自攻牙螺丝柱不宜频繁拆卸&#xff0c;因…

AI大模型应用(2)ChatGLM3本地部署及其在alpaca_zh数据集上的低精度微调

AI大模型应用(2)ChatGLM3部署及其在alpaca_zh数据集上的低精度微调 我们之前已经了解了HuggingFace中peft库的几种高效微调方法。 参数高效微调PEFT(一)快速入门BitFit、Prompt Tuning、Prefix Tuning 参数高效微调PEFT(二)快速入门P-Tuning、P-Tuning V2 参数高效微调PEFT…

C++第三十弹---C++继承机制深度剖析(中)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1、派生类的默认成员函数 1.1、派生类的构造函数 1.2、派生类的拷贝构造函数 1.3、派生类的赋值重载 1.4、派生类的析构函数 2、继承与友元 …

TL3568编译Kernel内核 make tl3568-evm.img -j16报错 ‘arch/arm64/boot/Image.lz4‘ failed

在编译Kernel时&#xff0c;遇到报错内容&#xff1a; /bin/sh: lz4c: command not found arch/arm64/boot/Makefile:31: recipe for target arch/arm64/boot/Image.lz4 failed make[1]: *** [arch/arm64/boot/Image.lz4] Error 1 arch/arm64/Makefile:139: recipe for target …

科普文:【支持信创、宣传国产】Alibaba Dragonwell JVM性能提升50%

4月5日&#xff0c;阿里云开放了新一代ECS实例的邀测[1]&#xff0c;Alibaba Dragonwell也在新ECS上进行了极致的优化。相比于之前的dragonwell_11.0.8.3版本&#xff0c;即将发布的dragonwell_11.0.11.6在SPECjbb2015[2] composite模式测试中&#xff0c;系统吞吐量max-jOPS提…

【算法】插值查找(对二分查找的优化)

引言 在二分查找中&#xff0c;对于相对较大的数或较小的数来说&#xff0c;查询效率是很低的&#xff0c;我们希望程序可以自适应待查询的数&#xff0c;使用插值算法 插值查找原理 1.插值查找算法类似于二分查找&#xff0c;不同的是插值查找每次从自适应 mid 处开始查找 2…

Airtest封装的Tidevice接口有多好用(二)

一、前言 上节课我们分享了一批Airtest封装的Tidevice接口&#xff0c;是有关获取设备信息的&#xff0c;还没看到的同学可以戳这里复习一下。那么本周我们继续来看一下Airtest还封装了哪些Tidevice的接口吧~ 二、Airtest封装的Tidevice接口 2.1 list_app(udid ,app_typeuse…

早得农元早享“富”!农元又双叒叕涨了!

农元升值设定的唯一途径&#xff0c;仅随着用户在平台每次的购物而升值&#xff0c;未来农元的价值升值甚至会达到几千、上万元人民币&#xff0c;真正实现了购物乐趣与财富增长的双重盛宴&#xff0c;让每一位平台用户都能享受到数字经济时代带来的红利。 快从消费者变为经营者…

警惕!六西格玛培训中不可不知的六大陷阱

近年来&#xff0c;随着六西格玛的普及&#xff0c;一些常见的培训陷阱也逐渐浮出水面&#xff0c;让不少求学者误入歧途。本文&#xff0c;深圳天行健企业管理咨询公司旨在为大家揭示六西格玛培训中的六大常见陷阱&#xff0c;真正掌握六西格玛的精髓。 陷阱一&#xff1a;速成…

KMP入门与算法题实践

基础知识 参考视频 下面是两个b站上个人借鉴学习的视频 第一个视频用来快速理解KMP&#xff1a; 【最浅显易懂的 KMP 算法讲解】 https://www.bilibili.com/video/BV1AY4y157yL/?share_sourcecopy_web&vd_sourced124eda224bf54d0e3ab795c0b89dbb0 第二、三个视频用来理…

vue3学习day01-vue3的优势、新的脚手架工具create-vue、创建vue3项目、vue3的项目文件内容、插件变化

1、vue3的优势 &#xff08;1&#xff09;更易维护&#xff1a;组合式api&#xff0c;更好的TypeScript支持 &#xff08;2&#xff09;更快的速度&#xff1a;重写diff算法&#xff0c;模版编译优化&#xff0c;更高效的组件化 &#xff08;3&#xff09;更小的体积&#x…

MES系统:生产实时监控与智能反馈,驱动制造业智能化升级

MES系统&#xff08;Manufacturing Execution System&#xff0c;制造执行系统&#xff09;通过集成多种技术手段和管理模块&#xff0c;实现了生产过程的实时监控与反馈。以下是实时监控与反馈具体实现的详细分析&#xff1a; 一、实时监控 1. 数据采集 传感器与设备集成&am…

nrm: npm 镜像源管理工具

nrm 是 “npm registry manager” 的缩写&#xff0c;是一个 npm 镜像源管理工具&#xff0c;用于在不同的 npm 镜像源之间快速切换&#xff0c;帮助开发者根据需要选择不同的源来加速包的下载或解决网络问题。 常用命令 详细介绍 以下是 nrm 的一些主要特性和用法&#xff1…

精美UI三方用户中心 新版QRuser用户中心主题 | 魔方财务模板

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 新版QRuser用户中心主题 | 魔方财务模板 本主题支持魔方财务3.5.7版本&#xff01;可自由切换魔方财务3.5.7版本与其他版本。 本主题基于官方default开发&#xff0c;主要面向企业&…