(五)CSharp-进一步理解接口

news2024/12/23 20:45:51

一、什么是接口

接口是指定一组函数成员而不实现它们的引用类型。

实现接口: 只能由类和结构来实现接口。

二、声明接口

接口声明不能包含以下成员:

  • 数据成员
  • 静态成员

接口声明只能包含如下类型的非静态成员函数的声明:

  • 方法
  • 属性
  • 事件
  • 索引器

接口的访问性和接口成员的访问性之间的区别:

  • 接口声明可以有任何的访问修饰符:public、protected、internal 或 private。
  • 接口成员是隐式 public 的,不允许有任何访问修饰符,包括 public。
    //正确,接口可以有访问修饰符
    public interface IMyInterface2
    {
        //报错,接口成员不允许有访问修饰符
        private int Method1(int nVar1, long lVar2);
    }

三、接口是引用类型

我们可以通过把类对象引用强制转换为接口类型来获取指向接口的引用。

    interface IIfc1
    {
        void PrintOut(string s);
    }

    class MyClass : IIfc1
    {
        public void PrintOut(string s)
        {
            Console.WriteLine($"Calling through:{ s }");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyClass mc = new MyClass();
            mc.PrintOut("object");//调用类对象的实现方法
            IIfc1 ifc = (IIfc1)mc;//将类对象的引用转换为接口类型的引用
            ifc.PrintOut("interface");//调用接口方法

            Console.ReadKey();
        }
    }

四、接口和 as 运算符

当我们把类对象引用强制转换为接口类型时,如果类并没有实现接口的引用(比如类没有继承对应的接口,或者类没有完全实现继承接口里的方法),强制转换操作会抛出一个异常。

那么可以通过使用 as 运算符来避免这个问题:

  • 如果类实现了接口,表达式返回指向接口的引用。
  • 如果类没有实现接口,表达式返回 null 而不是抛出异常。
ILiveBirth b = a as ILiveBirth;

if(b != null)
Console.WriteLine($"Baby is called:{b.BabyCalled()}");

五、实现具有重复成员的接口

问题: 由于类可以实现任意数量的接口(继承多个接口),有可能两个或多个接口成员具有相同的签名和返回类型。

解决: 类可以实现单个成员来满足所有包含重复成员的接口。(在例子中,实现的单个成员都属于 IIfc1 和 IIfc2)

   interface IIfc1
    {
        void PrintOut(string s);
    }

    interface IIfc2
    {
        void PrintOut(string s);
    }

    class MyClass : IIfc1, IIfc2
    {
        public void PrintOut(string s)
        {
            Console.WriteLine($"Calling through:{ s }");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyClass mc = new MyClass();
            mc.PrintOut("object");
            Console.ReadKey();
        }
    }

输出结果:

Calling through:object

六、多个接口的引用

    class Program
    {
        static void Main(string[] args)
        {
            MyClass mc = new MyClass();
            IIfc1 ifc1 = (IIfc1)mc;
            IIfc2 ifc2 = (IIfc2)mc;

            mc.PrintOut("object");

            ifc1.PrintOut("interface 1");
            ifc2.PrintOut("interface 2");
            Console.ReadKey();
        }
    }

输出结果:

Calling through:object
Calling through:interface 1
Calling through:interface 2

请添加图片描述

七、显式接口成员实现

如果我们希望为每一个接口分离实现,我们可以创建显式接口成员实现。

显式接口成员实现有如下特性:

  • 与所有接口实现相似,位于实现了接口的类或结构中。
  • 它使用限定接口名称来声明,由接口名称和成员名称以及它们中间的点分离符号构造。
   interface IIfc1{ void PrintOut(string s); }
    interface IIfc2{ void PrintOut(string s); }

    class MyClass : IIfc1, IIfc2
    {
        //不可用访问修饰符
         void IIfc1.PrintOut(string s)
        {
            Console.WriteLine($"IIfc1:{ s }");
        }

        void IIfc2.PrintOut(string s)
        {
            Console.WriteLine($"IIfc2:{ s }");
        }
    //类内访问显式接口成员
      public void Method()
        {
            //PrintOut("...");//编译错误
            ((IIfc1)this).PrintOut("interface 1");
        }
        
     }

    class Program
    {
        static void Main(string[] args)
        {
            MyClass mc = new MyClass();
            //获取接口的引用
            IIfc1 ifc1 = (IIfc1)mc;
            IIfc2 ifc2 = (IIfc2)mc;

            //mc.PrintOut("object");//错误
            //显式实现
            ifc1.PrintOut("interface 1");
            ifc2.PrintOut("interface 2");
            Console.ReadKey();
        }
    }

输出结果:

IIfc1:interface 1
IIfc2:interface 2

八、不同类实现一个接口的示例

    interface ILiveBirth
    {
        string BabyCalled();
    }

    class Animal { }

    class Cat:Animal, ILiveBirth
    {
        string ILiveBirth.BabyCalled()
        {
            return "kitten";
        }
    }

    class Dog : Animal, ILiveBirth
    {
        string ILiveBirth.BabyCalled()
        {
            return "puppy";
        }
    }

    class Bird : Animal
    {
        
    }

    class Program
    {
        static void Main(string[] args)
        {
            Animal[] animalArray = new Animal[3];
            animalArray[0] = new Cat();
            animalArray[1] = new Bird();
            animalArray[2] = new Dog();

            foreach(Animal a in animalArray)
            {
                ILiveBirth b = a as ILiveBirth;
                if (b != null)
                    Console.WriteLine($"Baby is called:{ b.BabyCalled() }");
            }

            Console.ReadKey();
        }
    }

输出结果:

Baby is called:kitten
Baby is called:puppy

请添加图片描述

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

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

相关文章

25张python代码速查表,让你python能力突飞猛进的秘诀!

在学习函数时,总是会有很多东西学得很快,遗忘得也很快。但其实在学习中,只需要知道相关参数,加以调整就够了。所以你可能需要这本秘籍! 即整理了Python科学速查表,就可以帮你解决以上的问题。当你在练习的时…

怎样正确做 Web 应用的压力测试?字节8年测试5个步骤给我看师了

Web应用,通俗来讲就是一个网站,主要依托于浏览器来访问其功能。 那怎么正确做网站的压力测试呢? 提到压力测试,我们想到的是服务端压力测试,其实这是片面的,完整的压力测试包含服务端压力测试和前端压力测…

高可用系统架构总结

文章目录 系统设计的一些原则海恩法则墨菲定律 软件架构中的高可用设计什么是高可用故障的度量与考核解决高可用问题具体方案 集群化部署负载均衡负载均衡实现内部服务外部服务数据库 负载均衡算法round-robinip_hashhash key 失败重试健康检查TCPHTTP 隔离线程隔离进程隔离集群…

华秋观察 | 通讯产品 PCB 面临的挑战,一文告诉你

印制电路板是电子产品的关键电子互联件,被誉为“电子产品之母”。随着电子产品相关技术应用更快发展、迭代、融合,PCB作为承载电子元器件并连接电路的桥梁,为满足电子信息领域的新技术、新应用的需求,行业将迎来巨大的挑战和发展机…

rocky9脚本py格式

在linux7上编写/root/CreateFile.py的python3脚本,创建20个文件/root/test/File01至/root/test/File20,如果文件存在,则先删除再创建;每个文件的内容同文件名,如File01文件的内容为”File01” 先在root目录下建立所需…

使用单片机遇到的几个问题及解决方案1

1.为什么我跟着视频学习的过程中,我没有找到“端口"的选项呢?我甚至没有出现“其他插口”。 想要找到设备管理器最快的方法就是: 首先如果把输入法调为大写形式,然后按下“WINX”,再按“M”就会出现一个设备管理…

python制作炸弹人游戏,一起来爆破消灭敌人吧

前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 《炸弹人》是HUDSON出品的一款ACT类型游戏,经典的第一作登陆在FC版本,游戏于1983年发行。 游戏具体操作是一个机器人放置炸弹来炸死敌人,但也可以炸死自己,还有些增强威力…

K8S之服务Service(十三)

1、Service概念: Kubernetes中的 Pod是有生命周期的,它们可以被创建,也可以被销毁,然而一旦被销毁pod生命就永远结束,这个pod就不存在了,通过ReplicaSets能够动态地创建和销毁Pod(例如&#xff…

【计算思维题】少儿编程 蓝桥杯青少组计算思维 数学逻辑思维真题详细解析第8套

少儿编程 蓝桥杯青少组计算思维题真题及解析第8套 1、下列哪个选项填到填到下图空缺处最合适 A、 B、 C、 D、 答案:D 考点分析:主要考查小朋友们的观察能力,从给定的图中可以看到,图中的线条都是有实现和虚

【C++ 学习 ⑨】- 万字详解 string 类(上)

目录 一、为什么学习 string 类? 二、标准库中的 string 类 三、C STL容器是什么? 四、string 类的成员函数 4.1 - 构造函数 4.2 - 赋值运算符重载 4.3 - 容量操作 4.4 - 遍历及访问操作 4.4.1 - operator[] 和 at 4.4.2 - 迭代器 4.5 - 修改…

Node.js 使用踩坑

重装电脑后,重装node.js 出现一个问题: npm install 会报错 按提示操作后 而npm run serve 会报xlsx和echart的错误,提示引用不对之类的,但是公司项目固定的,不可以随便改,而且之前是没问题的。 此时需要找…

华为OD机试真题B卷 Java 实现【数组拼接】,附详细解题思路

一、题目描述 现在有多组整数数组,需要将它们合并成一个新的数组。 合并规则,从每个数组里按顺序取出固定长度的内容合并到新的数组中,取完的内容会删除掉,如果该行不足固定长度或者已经为空,则直接取出剩余部分的内…

Anaconda教程,Python版本控制

Anaconda教程,Python版本控制 文章目录 Anaconda教程,Python版本控制1:Anaconda安装1.1:Windows1.2:Linux1.3:MacOS 2:Anaconda使用2.1:创建一个新的环境2.2:安装 Python 包2.3:激活…

hash模式下路由跳转页面不刷新

mode为hash时,纯粹页面,路由跳转过之后跳转上一级重复路由页面不会重新渲染 举个例子:当我在注册页面->注册状态页面->注册页面,在这个期间我从注册状态页面进行缓存的数据想要在注册页面使用,然而注册页面不会…

【YOLO系列】YOLO v5(网络结构图+代码)

文章目录 推理转换onnx网络架构SPP VS SPPFAutoAnchorLoss 参考 【YOLO系列】YOLO v3(网络结构图代码) 【YOLO 系列】YOLO v4-v5先验知识 【YOLO系列】YOLO v4(网络结构图代码) 我是在自己笔记本上配置的YOLO v5环境。首先&#x…

饼状图使用属性时,使用驼峰命名法

饼状图是使用D3.js等JavaScript库来绘制的,而JavaScript中的属性名通常采用驼峰式命名法,即第一个单词的首字母小写,后面单词的首字母大写,例如fontSize、fontWeight等。而CSS中的属性名采用连字符命名法,即单词之间用…

Top 5 Best Open Source Projects on GitHub 2023

这里介绍Github上 5 个增长最快的开源项目,它们为原有的解决方案提供了更加具有成本效益的替代方案,并为开发者、数据分析师和企业提供了高可用的工具产品。利用开源的优势,这5个项目拓展了强大而有效的解决方案,是值得收藏、分享…

比ureport好用的报表系统-VeryReport报表系统

随着数据时代的到来,数据成为企业管理和决策的重要依据。然而,在处理海量数据的同时,如何快速准确地生成各种形式的报表却成为了一个痛点。手工制作报表费时费力、容易出错;而传统的报表工具又复杂难用,无法满足不同用…

基于jsp+mysql+Spring+mybatis+Springboot的SpringBoot婚纱影楼摄影预约网站

运行环境: 最好是java jdk 1.8,我在这个平台上运行的。其他版本理论上也可以。 IDE环境: Eclipse,Myeclipse,IDEA或者Spring Tool Suite都可以,如果编译器的版本太低,需要升级下编译器,不要弄太低的版本 tomcat服务器环…

Linux下快速创建大文件的4种方法总结

1、使用 dd 命令创建大文件 dd 命令用于复制和转换文件,它最常见的用途是创建实时 Linux USB。dd 命令是实际写入硬盘,文件产生的速度取决于硬盘的读写速度,根据文件的大小,该命令将需要一些时间才能完成。 假设我们要创建一个名…