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

02011601 接口01-声明和实现接口、IComparable接口、接口引用和as运算符

02011601 接口01-声明和实现接口、IComparable接口、接口引用和as运算符

1. 什么是接口

  • 接口是指定一组函数成员而不实现他们的引用类型。只能类和接口来实现接口。

  • 使用接口的语法格式

using System;namespace Demo01
{interface IInfo // 声明接口{string GetName();string GetAge();}class CA : IInfo // 声明实现接口的类型{public string Name;public int Age;public string GetName() // 实现接口的方法{return Name;}public string GetAge() // 实现接口的方法{return Age.ToString();}}class Program{static void PrintInfo(IInfo item) // 传入接口的引用{Console.WriteLine($"Name:{item.GetName()}, Age:{item.GetAge()}");}static void Main(){CA cA = new CA() { Name = "Qinway", Age = 35 };PrintInfo(cA);Console.ReadLine();}}
}控制台输出
Name:Qinway, Age:35

2. 使用IComparable接口的示例

2.1 ICcomparable接口的引入
using System;namespace Demo01
{class Program{static void Main(){var myInt = new[] { 20, 4, 16, 9, 2 };Array.Sort(myInt);foreach (var i in myInt)Console.WriteLine($"{i}");Console.ReadLine();}}
}控制台输出
2
4
9
16
20说明:Array类的Sort方法在int数组上工作的很好,可以int型数组进行排序。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// Array类的Sort方法是否可以对自定义类数组进行排序?
class MyClass
{public int TheValue;
}
...
MyClass[] mc = new MyClass[5];
...
Array.Sort(mc); // 尝试使用Srot方法时抛出异常注意,Sort不能对MyClass对象数组进行排序,原因如下:
1. 它不知道如何比较用户定义的对象以及如何进行排序。
2. Array类的Sort方法其实依赖于一个叫做IComparable的接口,它声明在BLC中,包含唯一的方法CompareTo。
2.2 IComparable接口的声明
public interface IComparable
{int CompareTo(object obj); // 这里的方法实现直接是分号,即不包括实现。
}注意,尽管接口声明中没有为CompareTo方法提供实现,但ICompareTo接口的.NET文档中描述了该方法应该做的事情如下:
1. 在调用CompareTo方法时,它应该返回以下几个值
1.1 负整数 → 如果当前对象小于参数对象。
1.2 正整数 → 如果当前对象大于参数对象。
1.3 0 → 如果两个对象在比较时相等。
2. Sort使用的算法依赖于使用元素的CompareTo方法来决定两个元素的次序。
2.1 int类型实现了IComparable,但是在2.1中自定义的MyClass没有实现该接口。
2.2 因此当Sort尝试调用MyClass不存在的CompareTo方法时会抛出异常。
2.3 自定义类实现IComparable接口
  • 我们可以通过让类实现IComparable,让Sort方法可以用于MyClass类型的对象。要实现这一个接口,类或结构必须做两件事情。
    • 在基类列表中列出接口名称。
    • 为接口的每一个成员提供实现。
class MyClass : IComparable // 类实现接口
{public int TheValue;public int CompareTo(object obj) // 接口方法的实现{MyClass mc = (MyClass)obj;if(this.TheValue < mc.TheValue) return -1;if(this.TheValue > mc.TheValue) return 1;return 0;}
}说明:
1. 接口名称列在类声明的基类列表中。
2. 类实现了一个名为CompareTo的方法,它的参数类型和返回类型与接口成员一致。
3. 实现CompareTo方法以遵循接口文档的定义。也就是说,它将它的值传入方法的对象值进行比较,并据此返回0,-1或1。
4. 注意,在类中仅仅声明了CompareTo方法是不够的,类必须实现接口。

3. 声明接口

  • 接口声明不能包含一下成员
    • 数据成员
    • 静态成员
  • 接口声明只能包含如下类型的非静态成员函数的声明。
    • 方法
    • 属性
    • 事件
    • 索引器
  • 接口函数成员的声明不能包含任何实现代码,必须使用分号代替每一个成员声明的主体。
  • 按照惯例,接口名称必须重大写的I开始(如:ISaveable)。
  • 与类和结构一样,接口声明也可以分隔成分部接口声明。
// 声明接口的示例关键字      接口名称↓           ↓
interface IMyInterface 
{int DoStuff(int nVar1, long lVar2); // 分号代替函数成员主体double DoOtherStuff(string s, long x); // 分号代替函数成员主体
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
public interface IMyInterface // 接口可以有访问修饰符
{int void DoStuf01f(int x); // 默认为publicpublic int void DoStuff02(int x); // 错误写法,不能显示用publicprivate int void DoStuff03(int x); // 错误写法,不能有任何访问修饰符
}注意,接口访问性和接口成员的访问性之间有一些重要的区别。
1. 接口成员是隐式public的,不允许有任何访问修饰符,包括public也不能写。
2. 接口声明可以有任何访问修饰符,如:public,protected,internal,private。

4. 实现接口

4.1 实现结构基本格式
  • 只有类和结构可以实现接口,要实现接口,类或结构必须做到如下事项。
    • 在基类列表中包括接口名称。
    • 为每一个接口成员提供实现。
// 声明接口
interface IMyInterface 
{int DoStuff(int nVar1, long lVar2); double DoOtherStuff(string s, long x);
}// 实现接口
class MyClass : IMyInterface // @1 基类列表必须包含接口名称。
{int DoStuff(int nVar1, long lVar2) // @2 实现接口成员1{...}double DoOtherStuff(string s, long x) // @3 实现接口成员2{...}
}
4.2 实现接口的其它重要内容
  • 如果类实现了接口,它必须实现接口的所有成员。
  • 如果类派生自基类并实现了接口,基类列表中的基类名称必须放在所有接口之前。
  • 注意,只能有一个基类。
		   基类必须放在最前面           接口名称↓					  ↓
class Derived : MyBaseClass, IIfc1, IEnumerable, IComparable
{...
}

5.接口是引用类型

  • 接口不仅仅是类或结构要实现的成员列表,它是一个引用类型。
  • 我们不能通过类对象的成员访问接口。但是,我们可以通过把类对象引用强制转换为接口类型来获取指向接口的引用。
    • 一旦有了接口的引用,就可以使用“.”来调用接口的成员。
    • 注意,使用这个接口,不能调用不属于这个接口成员的类成员。
5.1 接口引用与类对象引用
// 从类对象引用获取接口引用的示例接口      转换为接口↓           ↓
IIfc1 ifc = (IIfc1)mc; // @1 获取接口的引用↑            ↑接口引用      类对象的引用ifc.PrintOut("Qinway"); // @2 使用接口的引用调用方法说明:
1. mc变量是一个实现了IIfc1接口的类对象的引用。
2. 将类对象的引用显式转换为指向接口的引用,并将这个接口引用赋值给变量ifc。
3. 可以省略显式转换部分,因为编译器可以隐式的将它转换成正确的接口,因为正确的接口可以从赋值语句的左端推断出来。
4. 在@2处,使用指向接口的引用来调用实现方法。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 接口引用调用方法和类对象引用调用方法示例
using System;namespace Demo01
{interface IIfc1{void PrintOut(string s);}class MyClass : IIfc1{public void PrintOut(string s){Console.WriteLine($"Call through: {s}");}}class Program{static void Main(){MyClass mc = new MyClass();mc.PrintOut("object");IIfc1 ifc01 = (IIfc1)mc; // 显式转换ifc01.PrintOut("interface");IIfc1 ifc02 = mc; // 隐式转换ifc02.PrintOut("interface");Console.ReadLine();}}
}控制台输出:
Call through: object
Call through: interface
Call through: interface
5.2 类对象引用与接口的引用之间关系
图片链接丢失

6. as运算符

  • 可以使用强制类型转换来获取对象接口的引用。
    • 此外,另一个更好的方式是使用as运算符。
    • 如果尝试将类对象引用强制转换为类为实现的接口的引用,强制类型转换会抛出异常。
    • 可以通过使用as运算符来避免抛出异常。
  • as运算符用法介绍
    • 如果类实现了接口,表达式指向接口的引用。
    • 如果类没有实现接口,表达式返回null而不是抛出异常。
             类对象引用  接口名称↓         ↓
ILiveBirth b   = a as ILiveBrith; // @1,使用as运算符,与强制类型转换(ILiveBrith)a一样↑        ↑接口引用  运算符if(b != null) // @2 对b进行判断Console.WriteLine($"Qinway");说明:
1. 在@1处,使用as运算符从类的对象获取接口引用。
2. 在@1处,as表达式的结果会把b的值设置为null或ILiveBrith接口的引用。
3. 在@2处,如果b为null,表示a没有对接口进行实现,如果b不为null,那么b可以调用接口成员方法。

结尾

书籍:C#图解教程

著:【美】丹尼尔 · 索利斯;卡尔 · 施罗坦博尔

译:窦衍森;姚琪琳

ISBN:978-7-115-51918-4

版次:第5版

发行:人民邮电出版社

※敬请购买正版书籍,侵删请联系85863947@qq.com※

※本文章为看书或查阅资料而总结的笔记,仅供参考,如有错误请留言指正,谢谢!※

http://www.sczhlp.com/news/13568/

相关文章:

  • (同余最短路)[arc084_b]Small Multiple
  • 02011601 接口01-声明和实现接口、IComparable接口、接口引用和类对象引用
  • 题解:深黯「军团」
  • Three.js实例化技术:高效渲染数千3D对象
  • 智慧农业(卫星遥感技术)
  • 快速切换jdk版本
  • 美团2026.8.16笔试个人题解
  • STM32F103C6T6资源列表
  • IDEA远程连接Docker
  • 【CANoe】创建和使用LOG
  • alembic upgrade head. NameError: name sqlmodel is not defined
  • Prometheus结合node_exporter实现自定义监控指标
  • Prometheus常用监控指标介绍
  • 烧写 Arduino BootLoader 的几种方法
  • odoo序列号 Sequences设置,生成 操作
  • MediaCodec的使用(音频解码二)
  • 微信永封解封教程
  • 题解:Physical Education Lessons
  • ODT 珂朵莉树详解
  • ISBN
  • 告别盲目招聘!Moka自定义报表一键诊断招聘瓶颈
  • 软考系统分析师每日学习卡 | [日期:2025-08-16] | [今日主题:规范化理论-范式判断]
  • Linux系统基础
  • 在本地部署Qwen大语言模型全过程总结
  • 快捷键
  • 8.16随笔
  • 2025年8月16日
  • 大一总结
  • unioffice校验
  • AtCoder Beginner Contest 419 ABCDEF 题目解析