C#中的接口(interface)
接口的命名规范
I+名词
接口与抽象类的区别
接口是由抽象类演变而来的。
抽象类是未完全实现逻辑的类,其内部可以有抽象成员,也可以有非抽象成员;且子类在覆写抽象成员时,需要修饰符override。
而接口是完全未实现逻辑的,其内部只允许存在抽象成员而不能包含非抽象成员,即不能包含数据成员和静态成员;且成员是隐式默认public和absolute的,不允许显式地写出来;子类在实现接口的方法时,不需要修饰符override。
接口声明只能包含如下类型的非静态成员函数的声明:
方法、属性、事件、索引器
实现接口
只有类和结构才能实现接口,在实现时应满足:
- 在基类列表中包括接口名称。
- 为每一个接口成员提供实现。
一个类可以同时继承一个基类和多个接口,不过在基类列表中基类名称应放置在接口名称之前。
如果在一个类实现的多个接口中,存在两个或多个接口的成员具有相同的签名和返回值类型,那么类可以实现单个成员来满足所有包含重复成员的接口。
接口的作用
让一个方法可以接受各种类型的对象,并且不管该类有什么样的结构。
比如,存在一个方法PrintIHuman(),如果要让其接受Student和Programmer这两个不同的类的对象,就需要让这两个类继承同一个接口:
namespace TestConsole
{//声明接口interface IHuman{void Action();}//声明Student类,其需要实现接口IHuman的方法Action()class Student : IHuman{public void Action(){Console.WriteLine("The student are studying...");}}//声明Programmer类,其与Student类有着不同的结构,实现Action()方法的方式也不相同class Programmer : IHuman{public String Name { get; set; }public void Action(){Console.WriteLine(Name + " is writing code...");}}//测试:class Program{static void PrintIHuman(IHuman ih){ih.Action();}static void Main(string[] args){Student stu = new Student();PrintIHuman(stu);Programmer prom = new Programmer();prom.Name = "Ivan";PrintIHuman(prom);}}
}
运行结果:
The student are studying…
Ivan is writing code…
我们可以这样理解:接口就是一种契约,有些方法只接收遵循某种契约的参数,以上面的代码为例,IHuman接口是一种契约,而PrintIHuman()这个方法只接收遵循IHuman这个契约的参数,当Student和Programmer这两个类都遵循IHuman这个契约时,就可以使用PrintIHuman()方法了。
可以认为,接口是为解耦而生的。例如,当一个方法需要某种契约的参数时,而此时遵守这个契约的类出了bug,在修复期间,方法就可以先去使用其他遵守这个契约的类;如果没有接口的话,这个方法和这个类之间的耦合度就很大了,当类出了问题,方法也会随之瘫痪,加大了维护难度和成本。
使用系统提供的接口
比如Array的sort方法,能对数组进行排序,但如果是我们自己写的类,想让sort方法对我们的类对象根据成员值大小进行排序,那sort是做不到的,除非我们的类实现了 IComparable 接口。
namespace TestConsole
{//实现接口:IComparable,要实现其方法:CompareToclass MyTest : IComparable{public int MyVar { get; set; }public int CompareTo(object obj){MyTest mt = (MyTest)obj;if (this.MyVar < mt.MyVar) return -1;if (this.MyVar > mt.MyVar) return 1;return 0;}} class Program{//打印数组元素static void printArray(MyTest[] mt){foreach (var item in mt){Console.Write(item.MyVar+" ");}Console.WriteLine("");}//测试static void Main(string[] args){var myInt = new[] { 20, 4, 47, 6, 1 };MyTest[] amt = new MyTest[5];for (int i = 0; i < 5; i++){amt[i] = new MyTest();amt[i].MyVar = myInt[i];}Console.WriteLine("排序前:");printArray(amt);Array.Sort(amt);Console.WriteLine("排序后:");printArray(amt);}}
}
运行结果:
排序前:
20 4 47 6 1
排序后:
1 4 6 20 47
is和as运算符
接口是引用类型,可以通过强制转换运算符来获取对象接口的引用,但这种操作会抛出异常,我们可以使用as运算符来解决这一问题。
is运算符则用来判断某个对象是否为某个类型。
Student stu = new Student(); //“Student”是实现了接口“IHuman”的类
IHuman ih = stu as IHuman; //类型转换
if (ih is null) //判断对象ih是否为空
{Console.WriteLine("ih is null");
}
if (ih is IHuman) //判断对象ih是否为IHuman类型
{Console.WriteLine("ih is IHuman");
}
if (ih is Student) //判断对象ih是否为Student类型
{Console.WriteLine("ih is Student");
}
运行结果:
ih is IHuman
ih is Student
多个接口的独立引用
如果一个类实现了多个接口,我们可以获取每一个接口的独立引用。
namespace TestConsole
{interface IStone{String Color { get; set; }}interface IMonkey{void Action();}class StoneMonkey : IStone, IMonkey{public String Color { get; set; }public void Action(){Console.WriteLine("I can subdue demons.");}}//测试:class Program{static void Main(string[] args){StoneMonkey sunWuKong=new StoneMonkey();IMonkey falseMonkey = sunWuKong as IMonkey; //falseMonkey独立引用了sunWuKong的IMonkey接口//falseMonkey可以使用Action()方法,但无法像sunWuKong一样使用Color属性falseMonkey.Action();sunWuKong.Color = "golden";sunWuKong..Action();}}
}
显式接口成员实现
前面提到过,单个类的单个方法可以满足多个接口的重复成员,但如果想要为每一个接口分离实现,则需要显式实现接口成员。
显示接口成员实现:使用限定接口名称来声明,由接口名称和成员名称以及它们中间的点分隔符号构成。此时public是隐式的,不能显式写出。
namespace TestConsole
{interface ITest1{void Action();}interface ITest2{void Action();}class MyClass : ITest1, ITest2{void ITest1.Action(){Console.WriteLine("1号接口");}void ITest2.Action(){Console.WriteLine("2号接口");}}class Program{static void Main(string[] args){MyClass mc = new MyClass(); //MyClass对象mc无法直接调用Action方法//可以通过类型转换来调用:((ITest1)mc).Action();//或者用接口类型创建的MyClass对象来调用:ITest2 it2 = new MyClass();it2.Action();}}
}
运行结果:
1号接口
2号接口
注意,以上的“Action()”不是类级别的方法,所以MyClass类的对象mc无法直接调用它。不过,存在显式接口成员实现时,类级别的实现是允许的,即MyClass类可以同时包含显式接口成员实现和类级别的实现:
class MyClass : ITest1, ITest2
{//显式接口成员实现void ITest1.Action(){Console.WriteLine("1号接口");}void ITest2.Action(){Console.WriteLine("2号接口");}//类级别的实现public void Action(){Console.WriteLine("类级别的实现");}
}class Program
{static void Main(string[] args){MyClass mc = new MyClass();mc.Action();ITest1 it1 = new MyClass();it1.Action();ITest2 it2 = new MyClass();it2.Action();}
}
运行结果:
类级别的实现
1号接口
2号接口
C#中的接口(interface)相关推荐
- 介绍Unreal Engine 4中的接口(Interface)使用C++和蓝图
这个教程是从UE4 Wiki上整理而来. 在C++中直接使用Interface大家应该很熟悉.只是简单先定义一个个有虚函数的基类,然后在子类中实现相应的虚函数.像这样的虚函数的基类一般概念上叫接口.那 ...
- php中的网络接口,php中的接口interface
* 接口 * 1.使用关键字:interface * 2.类是对象的模板,接口是类的模板 * 3.接口看作是一个特殊的类 * 4.接口中的方法,只声明不实现,与抽象类一样 * 5.接口中的方法必须是p ...
- java interface_Java中的接口(interface)
Java中提倡面向接口编程,而不是面向类编程,个人理解就是将做什么和怎么做分开,以实现松耦合的目的. 基本数据类型分四类八种 : 整型.浮点型.字符型.布尔型: 引用数据类型分三种 : 类 . 接口 ...
- php中的抽象类(abstract class)和接口(interface)
一. 抽象类abstract class 1 .抽象类是指在 class 前加了 abstract 关键字且存在抽象方法(在类方法 function 关键字前加了 abstract 关键字)的类. 2 ...
- 面向对象编程语言中的接口(Interface)
在大多面向对象的编程语言中都提供了Interface(接口)的概念.如果你事先学过这个概念,那么在谈到"接口测试"时,会不会想起这个概念来!?本篇文章简单介绍一下面向对象编程语言中 ...
- Java 中接口 interface 实例介绍
接口(interface) 有时必须从几个类中派生出一个子类,继承它们所有的属性和方法.但是,Java不支持多重继承.有了接口,就可以得到多重继承的效果. 接口(interface)是抽象方法和常量值 ...
- android中接口的作用是什么意思,详解Android接口Interface的使用和意义
本文介绍是Android的一个重要的东西,接口Interface,详解两个方面: (1)Java是继承的,接口Interface是可以多个的,恰恰弥补了这个缺点. (2)回调,接口Interface里 ...
- typescript中的类型type与接口interface
typescript中的type相当于是给类型起一个新的名字 基本用法: 比如我想声明一个类型为number的年龄age,刚开始学typescript,我们可能会这样写 let age:number ...
- c#中抽象类(abstract)和接口(interface)的相同点与区别
相同点: 1.都可以被继承 2.都不能被实例化 3.都可以包含方法声明 4.派生类必须实现未实现的方法 区别: 1.抽象基类可以定义字段.属性.方法实现.接口只能定义属性.索引器.事件.和方法声明,不 ...
最新文章
- Laravel安装后没有vendor文件夹
- jquery radio 取值
- delphi公共函数 UMyPubFuncFroc--版权所有 (C) 2008 勇者工作室
- java nifty_Java NiftyDialogBuilder類代碼示例
- nginx php动态编译加载模块.
- 【计算理论】计算理论总结 ( 图灵机设计示例 ) ★★
- PUT or POST
- 快速寻找满足条件的两个数
- SVN报错working copy is not uptodate
- ABAP并发计算的一个实例
- 常用决策树集成模型Random Forest、Adaboost、GBDT详解
- ❤️❤️❤️【资料免费领取】简历模板、职场PPT模板、硬核学习资料+PDF资料(Java、Python、大数据、机器学习)❤️❤️❤️
- 人工智障学习笔记——机器学习(4)支持向量机
- Linux正则表达式与grep
- Android 爆发病毒,华米 OV 均受影响;微信宣战百度搜索;抖音遭约谈 | CSDN极客头条...
- java抽象类的说明
- Python面试必备!最全面的重点知识汇总,建议收藏!
- 轻松安装IP地址位置查询工具nali
- 直面大数据撞击这个时代——畅享网成功举办大数据应用沙龙
- 字模显示字符串C语言,[求助]关于点阵字模显示
热门文章
- Python实现对图像进行掩膜遮罩处理
- 如何用计算机做排列函数,25个电脑办公技巧 办公族必懂的电脑小技巧 (全文)
- Benchmark分析[4]: parsec.cannel(备)
- linux根据内容搜索指定文件
- “爱心助考 为梦护航”雷锋志愿者在行动
- Linux 硬盘分区、分区命名和分区格式化
- 40(公式累加求和)
- 超级计算机过滤器,时间,是最好的过滤器,会留下最值得的人
- 测试开发 - 十年磨一剑(三)UI自动化与Selenium
- java awt自学1 container小案例