C#【高级篇】 C# 接口(Interface)

您所在的位置:网站首页 光纤中的接头都有哪门子些那个是使用最多的 C#【高级篇】 C# 接口(Interface)

C#【高级篇】 C# 接口(Interface)

2024-07-10 13:16| 来源: 网络整理| 查看: 265

C#学习汇总 - 总目录

C#【高级篇】 C# 接口(Interface) 前言接口和抽象类的理解: 一、定义接口二、实现接口三、接口继承总结补充实例1【加深接口的理解】实例2【重要:结构体实现接口后是值类型还是引用类型?】接口和抽象类该如何取舍?【 接口和抽象类的区别】实例3【抽象类继承接口】

前言

接口定义了所有类继承接口时应遵循的语法合同。接口定义了语法合同 “是什么” 部分,派生类定义了语法合同 “怎么做” 部分。

接口定义了属性、方法和事件,这些都是接口的成员。

接口只包含了成员的声明。 成员的定义是派生类的责任。 接口提供了派生类应遵循的标准结构。

接口使得实现接口的类或结构体在形式上保持一致。

接口在程序设计中的作用为充当类或结构的功能界面,接口的属性、方法等属于抽象描述必须通过类或结构的实现才能使用。接口是使用者只知道接口有些什么功能,却不知道功能如何实现、由谁实现,这给程序的设计留下了很大的灵活性。

例如某个项目由多个功能模块组成,每个模块由一个程序员完成,程序员只需编写完模块功能的实现后,留下该模块的接口供其他人使用。其他人在程序中只需直接使用接口的功能,而不必了解接口的功能如何实现等问题。

接口和抽象类的理解:

抽象类在某种程度上与接口类似,但是,它们大多只是用在当只有少数方法由基类声明由派生类实现时。

接口本身并不实现任何功能,它只是和声明实现该接口的对象订立一个必须实现哪些行为的契约。

抽象类和接口都不能直接实例化,但允许派生出具体的,具有实际功能的类。

一、定义接口

接口使用 interface 关键字声明,它与类的声明类似。接口声明默认是 public 的。下面是一个接口声明的实例:

interface IMyInterface { void MethodToImplement(); }

以上代码定义了接口 IMyInterface。通常接口命令以 I 字母开头,这个接口只有一个方法 MethodToImplement(),没有参数和返回值,当然我们可以按照需求设置参数和返回值。

值得注意的是,该方法并没有具体的实现。

二、实现接口

接下来我们来实现以上接口:InterfaceImplementer.cs

using System; interface IMyInterface { // 接口成员 void MethodToImplement(); } class InterfaceImplementer : IMyInterface { static void Main() { InterfaceImplementer iImp = new InterfaceImplementer(); iImp.MethodToImplement(); Console.ReadLine(); } public void MethodToImplement() { Console.WriteLine("MethodToImplement() called."); } }

InterfaceImplementer 类实现了 IMyInterface 接口,接口的实现与类的继承语法格式类似:

class InterfaceImplementer : IMyInterface

继承接口后,我们需要实现接口的方法 MethodToImplement() , 方法名必须与接口定义的方法名一致。

三、接口继承

以下实例定义了两个接口 IMyInterface 和 IParentInterface。

如果一个接口继承其他接口,那么实现类或结构就需要实现所有接口的成员。

以下实例 IMyInterface 继承了 IParentInterface 接口,因此接口实现类必须实现 MethodToImplement() 和ParentInterfaceMethod() 方法:

using System; interface IParentInterface { void ParentInterfaceMethod(); } interface IMyInterface : IParentInterface { void MethodToImplement(); } class InterfaceImplementer : IMyInterface { static void Main() { InterfaceImplementer iImp = new InterfaceImplementer(); iImp.MethodToImplement(); iImp.ParentInterfaceMethod(); Console.ReadLine(); } public void MethodToImplement() { Console.WriteLine("MethodToImplement() called."); } public void ParentInterfaceMethod() { Console.WriteLine("ParentInterfaceMethod() called."); } }

实例输出结果为:

MethodToImplement() called. ParentInterfaceMethod() called. 总结 接口的定义:指定一组函数成员而不实现成员的引用类型,其它类型和接口可以继承接口。接口是“是什么”的规范,继承类或结构体是“怎么做”的具体实现。接口的特点:见 补充:一、二接口的应用场景:见实例1来理解接口和抽象类的区别 补充

一、接口注意的几点:

接口方法不能用public abstract等修饰。接口内不能有字段变量,构造函数。接口内可以定义属性(有get和set的方法)。如string color { get ; set ; }这种。实现接口时,必须和接口的格式一致。必须实现接口的所有方法。

二、接口的定义是指定一组函数成员而不实现成员的引用类型,其它类型和接口可以继承接口。接口主要有以下特点:

通过接口可以实现多重继承,C# 接口的成员不能有 public、protected、internal、private 等修饰符。原因很简单,接口里面的方法都需要由外面接口实现去实现方法体,那么其修饰符必然是 public。C# 接口中的成员默认是 public 的。接口成员不能有 new、static、abstract、override、virtual 修饰符。有一点要注意,当一个接口实现一个接口,这2个接口中有相同的方法时,可用 new 关键字隐藏父接口中的方法。接口中只包含成员的签名,接口没有构造函数,所以不能直接使用 new 对接口进行实例化。接口中只能包含方法、属性、事件和索引的组合。接口一旦被实现,实现类必须实现接口中的所有成员,除非实现类本身是抽象类。C# 的类是单继承,接口是解决 C# 里面类可以同时继承多个基类的问题。 实例1【加深接口的理解】

每个员工的属性、方法等都是相似的,这时就可以规范一个接口,而不是每个员工都搞个类。

class Program { static void Main(string[] args) { IWorker james1 = new James1(); IWorker james2 = new James2(); james1.work("设计"); james2.work("编程"); //从这个例子我体会到了有接口的好处,可以想象如果又来了新的员工。 //如果不采用接口,而是每个员工都有一个单独的类,这样就会容易出错。 //如果有接口这种协议约束的话,那么只要实现了接口就肯定有接口里声明的方法,我们只需拿来调用。 Console.ReadLine(); } } public interface IWorker{ void work(string s); } class James1 : IWorker { public void work(string s) { Console.WriteLine("我的名字是James1,我的工作是" +s); } } class James2 : IWorker { public void work(string s) { Console.WriteLine("我的名字是James2,我的工作是"+s); } } 实例2【重要:结构体实现接口后是值类型还是引用类型?】

在C#中数据类型分为值类型和引用类型 值类型:结构体、枚举 引用类型:类、接口、数组、委托

在结构使用时,结构可以实现接口。这时就有一个问题“结构体实现接口后是值类型还是引用类型?”。带着这个问题,我们看下面这段代码。

using System; namespace ConsoleApp1 { //结构体班级 struct StructClass : IClass { public int Count;//人数 public void AddStudent() { Count++; } public void ShowCount() { Console.WriteLine(Count); } } //接口 interface IClass { void AddStudent();//添加学生 void ShowCount();//显示学生人数 } class Program { static void Main(string[] args) { StructClass s1 = new StructClass(); StructClass s2 = s1; s1.AddStudent(); s1.ShowCount(); //输出1 s2.ShowCount(); //输出0 //说明s2和s1不指向同一个对象,s2=s1是创建了一个s1的副本 //这是值类型很显著的标志 IClass ic1 = new StructClass(); IClass ic2 = ic1; ic1.AddStudent(); ic1.ShowCount();//输出1 ic2.ShowCount();//输出1 //说明s2和s1指向同一个对象,s2=s1是将s1的引用赋给s2 //这是引用类型很显著的标志 Console.ReadLine(); } } }

运行结果:

1 0 1 1

最后得出结论: 当我们声明对象(s1、s2)是结构体类型时,对象是值类型,对象在栈中创建 当我们声明对象(ic1、ic2)是接口类型时,对象是引用类型,对象在堆中创建

接口和抽象类该如何取舍?【 接口和抽象类的区别】

接口和抽象类非常相似,两者都无法实例化,并且未实现部分都由派生类实现,其应用模型如下图: 在这里插入图片描述 结合上图,接口和抽象类的主要区别主要有以下几点:

抽象类只能派生类,而接口可以派生类和结构。抽象类的派生类也可以是抽象类,即抽象成员在派生类中不一定被完全实现。 而接口要求其派生类或结构必须完全实现其成员。抽象类可以包含已经实现的成员,可以包含字段。 而接口只包含未实现的成员,不能包含字段。并且接口及所含成员必须为public访问级别。类只能继承一个抽象类,但可以继承(实现)多个接口。

进一步理解:

在具体的程序设计中,抽象类和接口的取舍应视程序的需要而定。抽象类可以用于归纳—组相似的、有共同特性的类,然后将这些类共同的成员提取到抽象类中,使抽象类作为这组类的基类。这样做到了代码的复用,不但节约了代码量,也减轻了维护的复杂度。然后将这组类中相似的方法或属性提取到抽象类中,成为抽象类的抽象成员,不提供具体实现,由这组类自己完成不同的实现。

说明:抽象类的应用非常类似于网页制作中的CSS外部样式文件,大量风格相同的页面可以共用这个CSS文件,并且在页面中可以对部分CSS属性进行改写。

而接口是一组类的功能集合,也可以说是一组类的协定集合,这组类负责实现这些功能,可以说接口内含的成员都是抽象的。类可以实现多个接口,这样可将意图和实现分离,接口可以暴露给其他程序直接使用,并且可以很方便地进行功能的扩展。 实例3【抽象类继承接口】

抽象类也可以实现接口,这时抽象类必须实现所有的接口成员。请看以下实例:

using System; namespace ConsoleApp1 { interface IMyTest { void Test(); int Add(int a, int b); } public abstract class ClassA : IMyTest { public void Test() { Console.WriteLine("test"); } public int Add(int a, int b) { return a + b; } public abstract int Sub(int a, int b); } public class ClassB : ClassA { public override int Sub(int a, int b) { return a - b; } } class Program { static void Main(string[] args) { ClassB clsB = new ClassB(); int addresult = clsB.Add(1, 3); int subresult = clsB.Sub(4, 3); ; clsB.Test(); Console.WriteLine(addresult); Console.WriteLine(subresult); Console.ReadKey(); } } }

运行结果:

test 4 1

C#学习汇总 - 总目录



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3