C# 继承,抽象,接口,泛型约束,扩展方法

news2024/11/26 17:30:10

文章目录

  • 前言
  • 模拟需求
    • 场景模拟
      • 重复性高的需求
        • 初始类结构
        • 继承优化
          • 抽象类
        • 需求1:打印CreateTime
          • 方法1:使用重载
          • 方法2:基类函数
          • 方法3:泛型约束
          • 方法3.1:普通泛型方法
          • 方法3.2:高级泛型约束,扩展方法
        • 总结
      • 番外篇:泛型方法和接口
        • 泛型约束抽象接口
  • 总结

前言

以前计算机本科学习的时候,我就知道了继承,重载,接口,抽象,泛型等概念。本章优先讲解继承,接口,抽象,泛型这一组概念。如果说继承,抽象只是为了标准化代码,规范程序编写的话,那么泛型约束就是给于了继承抽象这个写法的必要性。

c# 继承

浅谈C#中的抽象类(abstract)和接口(interface)

C#泛型约束

模拟需求

因为我干的是上位机工作,这里我就讲解一下我用到的场景。上位机的代码重复性很高,泛型约束就是用于解决此类问题。

场景模拟

我是A公司,我有多种(为了简单按两种算)产品,这2种产品有一下两个特质

  • 每个产品存数据库的字段有完全相同的3个字段
    • Id:数据库Id
    • DeivceId:设备唯一Id,全部种类产品唯一的Id。
    • CreateTime:数据录入数据库时间

重复性高的需求

我们现在有个需求,给每个类添加一个打印CreateTime的方法

初始类结构
 public class DeviceA
 {
     public string DeviceId { get; set; }

     public long Id { get; set; }    

     public DateTime CreateTime { get; set; }

     public string ValueA {  get; set; }
 }

 public class DeviceB
 {

     public string DeviceId { get; set; }

     public long Id { get; set; }

     public DateTime CreateTime { get; set; }

     public string ValueB { get; set; }

 }
继承优化

继承的目的就是为了减少重复的字段

public class DeviceA:DeviceBase
{
    public string ValueA {  get; set; }
}

public class DeviceB : DeviceBase
{
    public string ValueB { get; set; }

}
/// <summary>
/// 使用基类优化代码
/// </summary>
public class DeviceBase
{
    public string DeviceId { get; set; }

    public long Id { get; set; }

    public DateTime CreateTime { get; set; }
}
抽象类

我们也可以在基类上面添加abstract关键字

public abstract class DeviceBase
{
    public string DeviceId { get; set; }

    public long Id { get; set; }

    public DateTime CreateTime { get; set; }

}

区别就是抽象类无法实例化
在这里插入图片描述

那么抽象类的意义就是为了告诉你,我的基类是没有任何实际意义的,我单纯就是为了继承用的

需求1:打印CreateTime
方法1:使用重载
static void Main(string[] args)
{
    var DeviceA = new DeviceA() { CreateTime = DateTime.Now};
    var DeviceB = new DeviceB() { CreateTime = DateTime.Now };
    PrintCreateTime(DeviceA);
    PrintCreateTime(DeviceB);
}
public static void PrintCreateTime(DeviceA deviceA)
{
    Console.WriteLine($"{deviceA.CreateTime}");
}

public static void PrintCreateTime(DeviceB deviceB)
{
    Console.WriteLine($"{deviceB.CreateTime}");
}
方法2:基类函数
internal class Program
{
    static void Main(string[] args)
    {
        var DeviceA = new DeviceA() { CreateTime = DateTime.Now};
        var DeviceB = new DeviceB() { CreateTime = DateTime.Now };
		DeviceA.PrintCreateTime();
		DeviceB.PrintCreateTime();
    }
 
}

/// <summary>
/// 使用基类优化代码
/// </summary>
public class DeviceBase
{
	·······
    public void PrintCreateTime()
    {
        Console.WriteLine(CreateTime.ToString());
    }
}
方法3:泛型约束
方法3.1:普通泛型方法
        static void Main(string[] args)
        {
            var DeviceA = new DeviceA() { CreateTime = DateTime.Now};
            var DeviceB = new DeviceB() { CreateTime = DateTime.Now };
            PrintCreateTime(DeviceA);
            PrintCreateTime(DeviceB);
        }
        /// <summary>
        /// 泛型约束DeviceBase基类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        public static void PrintCreateTime<T>(T model)where T : DeviceBase
        {
            Console.WriteLine(model.CreateTime.ToString());
        }
方法3.2:高级泛型约束,扩展方法

C#小轮子:扩展方法

internal class Program
{
    static void Main(string[] args)
    {
        var DeviceA = new DeviceA() { CreateTime = DateTime.Now};
        var DeviceB = new DeviceB() { CreateTime = DateTime.Now };
        DeviceA.PrintCreateTime();
        DeviceB.PrintCreateTime();
    }

}

public static class DeviceExtension
{
    /// <summary>
    /// 扩展方法是更高级的泛型方法,但是需要一个静态类扩展
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="model"></param>
    public static void PrintCreateTime<T>(this T model) where T : DeviceBase
    {
        Console.WriteLine(model.CreateTime.ToString());
    }
}
总结
优点缺点
重载更灵活,每个类都可以定制重复性高
基类方法降低重复度耦合度高,过多会导致基类臃肿,不符合属性类规范
泛型约束降低重复度,耦合度低,易于扩展。不能访问基类以外的属性
扩展方法最强的扩展性,完美代替基类方法需要单独一个静态类

属性类:是我自己的规范。就是基础的属性类只有属性和构造函数,没有方法。

番外篇:泛型方法和接口

有些时候我们设备类的逻辑特别的复杂,比如每个产品都有四个方法:

  • 连接
  • 发送
  • 接受
  • 关闭连接
public interface IDevice
{
    public void Connect();

    public void Send();
    public void Recive();

    public void Close();

}
public class DeviceA : DeviceBase, IDevice
{
    public string ValueA {  get; set; }

    public void Close()
    {
        throw new NotImplementedException();
    }

    public void Connect()
    {
        throw new NotImplementedException();
    }

    public void Recive()
    {
        throw new NotImplementedException();
    }

    public void Send()
    {
        throw new NotImplementedException();
    }
}

public class DeviceB : DeviceBase, IDevice
{
    public string ValueB { get; set; }

    public void Close()
    {
        throw new NotImplementedException();
    }

    public void Connect()
    {
        throw new NotImplementedException();
    }

    public void Recive()
    {
        throw new NotImplementedException();
    }

    public void Send()
    {
        throw new NotImplementedException();
    }
}
泛型约束抽象接口
static void Main(string[] args)
{
    var DeviceA = new DeviceA() { CreateTime = DateTime.Now};
    var DeviceB = new DeviceB() { CreateTime = DateTime.Now };
    GetData(DeviceA);
    GetData(DeviceB);
}

/// <summary>
/// 泛型约束也可以约束接口
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model"></param>
public static void GetData<T>(T model) where T : IDevice
{
    model.Connect();
    model.Send();
    model.Recive();
    model.Close();
}

总结

不是说只能用泛型约束去解决问题,而且泛型约束和扩展方法更具有扩展性,低耦合的特点。大家可以根据自己代码的习惯选择性的使用。

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

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

相关文章

Linux cat命令

连接文件并打印输出到标准输出设备。cat 命令可以用来显示文本文件的内容&#xff08;类似于 DOS 下的 type 命令&#xff09;&#xff0c;也可以把几个文件内容附加到另一个文件中&#xff0c;即连接合并文件。 关于此命令&#xff0c;有人认为写 cat 命令的人是因为喜欢猫&am…

canal 同时监听两个数据库实例

我有两个数据库实例 test和test2 复制一个example 并修改为example2 修改canal.properties文件 找到 destinations 修改为监听example和example2实例 把canal.destinations example 修改为 canal.destinations example,example2 在example目录中修改实例配置文件 instance…

java版小程序商城免费搭建-直播商城平台规划及常见的营销模式有哪些?电商源码/小程序/三级分销

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

centos7安装docker容器

卸载老版本&#xff1a; $ sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine/var/lib/docker/路径下存在镜像、数据卷、容器等&#xff0c;在卸载的时候是不会自动删除…

JAVA字符串格式化——String.format()的使用

引言 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象。熟悉C语言应该记得C语言的sprintf()方法&#xff0c;两者有类似之处。format()方法有两种重载形式。 重载 // 使用当前本地区域对象&#xff08;Locale.getDefault()&#xff09;&#xff0c;制定…

软件测试面试题之测试基础,想轻松应对面试,看完这篇就够了

软件测试的流程是什么&#xff1f;&#xff08;测试流程&#xff09; &#xff08;1&#xff09;需求调查&#xff1a;全面了解系统概况、应用领域、软件开发周期、软件开发环境、开发组织、时间安排、功能需求、性能需求、质量需求及测试要求等。根据系统概况进行项目所需的人…

【计算机网络】物理层知识

目录 1、物理层的基本概念 2、数据通信的基础知识 2.1、数据通信系统模型 2.2、信道的几个基本概念 3、物理层下面的传输媒体 4、信道复用技术 1、物理层的基本概念 物理层考虑的是怎样才能在连接各种计算机的传输媒体上传输数据比特流&#xff0c;而不是指具体的 传输媒…

数据标注工具【LabelImg】安装使用 用VOC制作自己的数据集

labelImg的安装 ⭐️LabelImg简介⭐️LabelImg的安装⭐️labelImg标注数据集⭐️利用VOC制作自己的数据集 ⭐️LabelImg简介 Labelimg是一款开源的数据标注工具&#xff0c;标签可用于分类和目标检测&#xff0c;它是用python写的&#xff0c;并使用Qt作为其图形界面&#xf…

漏刻有时百度地图API实战开发(2)文本标签显示和隐藏的切换开关

项目说明 在百度地图开发的过程中&#xff0c;如果遇见大数据量POI标注展示或在最佳视野展示时&#xff0c;没有文本标签&#xff0c;会不清楚具体标注的代表的意义&#xff1b;如果同时显示大量的文本标签&#xff0c;又会导致界面杂乱且无法清晰查看&#xff0c;因此&#x…

Leetcode-160 相交链表

双指针&#xff1a;遍历两次 a重bb重a /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) {* val x;* next null;* }* }*/ public class Solution {public ListNode getInter…

Vue3:一页多题答案提示及循环radio和checkbox混合使用

一页多题&#xff0c;类型包括单选&#xff08;单选、判断&#xff09;和多选&#xff0c;radio和checkbox混合使用&#xff0c;答案检验数据匹配&#xff0c;正确答案格式化&#xff0c;答案提交数据格式化&#xff0c;数据提交。 效果&#xff1a; 数据获取&#xff1a; 数据…

伊朗黑客对以色列科技和教育领域发起破坏性网络攻击

导语 近期&#xff0c;以色列的高等教育和科技领域遭受了一系列破坏性的网络攻击。这些攻击始于2023年1月&#xff0c;旨在部署以前未记录的数据清除恶意软件。在最近的攻击中&#xff0c;攻击者试图窃取个人身份信息和知识产权等敏感数据。本文将介绍这些攻击的具体细节&#…

实施电子采购的6个有效步骤

耗时又费力&#xff0c;手动采购之苦相信大家都受够了&#xff0c;现在越来越多的企业正在实施电子采购策略。根据CIPS的《2022年采购与供应数字化报告》&#xff0c;多达95%的企业在采购与供应商管理中采用了技术。 但采用技术并不能保证立竿见影的效果。企业需要制定好电子采…

word统计全部字符数。

问题描述&#xff1a;在投稿SCI论文时&#xff0c;有时会要求提交一个highlight文档&#xff0c;要求不超过85个字符。 具体如下&#xff1a;maximum 85 characters per bullet point including spaces 这里的字符不单单包括字母和汉字&#xff0c;还包括标点和空格键。那么如…

Linux 安装 Nginx 并将其配置为系统服务(详细图文)

目录 前言安装 Nginx安装依赖项下载Nginx解压Nginx编译和安装防火墙设置启动Nginx 配置 Nginx 为系统服务配置 Nginx 服务文件启动 Nginx 服务设置开机自启动检查 Nginx 状态停止 Nginx 服务重启 Nginx 服务 卸载 Nginx结语 前言 Nginx是一款卓越的高性能Web服务器&#xff0c…

【Unity细节】Json序列化时出现:An item with the same key has already been added. Key:

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 &#x1f636;‍&#x1f32b;️收录于专栏&#xff1a;unity细节和bug &#x1f636;‍&#x1f32b;️优质专栏 ⭐【…

RFID系统

目录 在物联网应用中有三项关键技术 读写器 电子标签 工作原理 阅读器的组成及作用&#xff1a; 电子标签的组成及作用&#xff1a; RFID系统的组成 接口方式 在物联网应用中有三项关键技术 在物联网应用中有三项关键技术 1、传感器技术&#xff1a;这也是计算机应用中…

操作系统引论(一)

操作系统的地位和目标 计算机系统的组成 系统软件是和硬件相关的&#xff0c;这是它本质的特征。 操作系统在计算机系统中的地位 操作系统的设计目标 可扩充性是面向未来的。 操作系统的作用 1&#xff09;用户与计算机硬件系统之间的接口 2&#xff09;计算机系统资源的管…

阿里终面:10亿数据如何快速插入MySQL?

最快的速度把10亿条数据导入到数据库&#xff0c;首先需要和面试官明确一下&#xff0c;10亿条数据什么形式存在哪里&#xff0c;每条数据多大&#xff0c;是否有序导入&#xff0c;是否不能重复&#xff0c;数据库是否是MySQL&#xff1f; 假设和面试官明确后&#xff0c;有如…

第十五届蓝桥杯模拟赛(第一期)

大家好&#xff0c;我是晴天学长&#xff0c;本次分享&#xff0c;制作不易&#xff0c;需要的小伙伴可以点赞关注评论一波哦&#xff01;后续会继续更新的。&#x1f4aa;&#x1f4aa;&#x1f4aa; 还在持续更新中&#xff0c;目前只更新了部分内容。 一 .找数位 问题描述 …