Console.WriteLine( (=・ω・=) 🍺🍺 );|

韩白白zz

园龄:9年4个月粉丝:3关注:12

🔖C#
2022-04-25 23:14阅读: 111评论: 0推荐: 0

C#-接口interface

接口介绍

接口就是包含一组方法声明而没有定义的类型,接口是引用类型。

C#中的接口非常类似于C++中的抽象类,包含一些纯虚函数,只有方法的声明,没有实现。需要派生类来继承它,并实接口中的方法。

一个简单的接口使用示例:

using Custom;

//主函数
void Main()
{
    CustomA objA = new CustomA();
    CustomB objB = new CustomB();

    test(objA);
    test(objB);
}

//在这里以接口类型传入参数
void test(ICustomIfc obj)
{
    obj.Add();
    obj.Remove();
}

namespace Custom
{
    //自定义接口
    interface ICustomIfc
    {
        public void Add();
        public void Remove();
    }

    //自定义类A,继承接口
    class CustomA : ICustomIfc
    {
	public void Add()
	{
	    Console.WriteLine("CustomA Add");
	}

	void ICustomIfc.Remove()
	{
	    Console.WriteLine("CustomA Remove");
	}
    }

    //自定义类B,继承接口
    class CustomB : ICustomIfc
    {
	public void Add()
	{
	    Console.WriteLine("CustomB Add");
	}

	void ICustomIfc.Remove()
	{
	    Console.WriteLine("CustomB Remove");
	}
    }
}//namespace

输出:

CustomA Add
CustomA Remove
CustomB Add
CustomB Remove

接口的类型、存储和作用

接口类型和类类型一样,都是引用类型,也就是说一个接口变量(一般叫接口引用)和类对象一样,其实只是一个引用,存储在栈中;而真正的数据是存储在堆中。

代码示例:

//三种从类对象转为接口引用的方式
//主函数
void Main()
{
    CustomA objA = new CustomA();
    objA.Add();
	
    //隐式转换
    ICustomIfc ifc1 = objA;
    ifc1.Add();

    //显示转换
    ICustomIfc ifc2 = (ICustomIfc)objA;
    ifc2.Add();

    //使用as运算符转换,实际中我们要使用as来转,这样更安全
    //其他转换错误时会抛出异常,异常多了会严重降低代码执行速度
    //as运算符转换错了会返回null,不会报异常
    ICustomIfc ifc3 = objA as ICustomIfc;
    ifc3?.Add(); //或者使用if判断,但这样更简洁
}

存储接口图:

作用:

统一类型,实现与类型无关的程序。以下只是我了解到的应用场景,可能还有很多其他的。

1、应用于函数参数,让方法的参数能够与类型无关,也就是一个类型的参数,能兼容好几种类型

2、应用于普通的对象调用方法,实现多态,使用接口引用调用不同派生类的同一个方法。

接口声明

接口可以声明以下非静态成员,并且可以不用加访问修饰符,默认都是public的,不能用private和protect修饰。

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

代码示例:

//自定义接口, 接口名称不以I开头不会报错,但是按照惯例都会以I开头
//接口声明可以使用public、protected、internal和private修饰
public interface ICustomIfc
{
    //int val = 10; //错误,不能包含字段
    int Prop {get; set;} //可以包含属性

    public void Add();
    public void Remove();

    double func1(); //不加修饰符默认为public
    //private double func2(); //错误,不能包含私有或保护方法
    //public static void func3(); //错误,不能包含静态方法

    public delegate void MyDel(int param); //可以包含委托类型,子类不用实现
    public event MyDel MyEvent; //可以包含事件成员,且子类必须实现

    //可以有方法实现,编译不会报错
    private double func2()
    {
        return 2;
    }
}

//继承接口
class CustomA : ICustomIfc
{
    public event ICustomIfc.MyDel MyEvent; //实现接口事件成员

    public void Add()
    {
    	Console.WriteLine("CustomA Add");
    }

    void ICustomIfc.Remove()
    {
    	Console.WriteLine("CustomA Remove");
    }

    public double func1()
    {
    	Console.WriteLine("CustomA func1");
    	return 0;
    }
}

接口实现

接口的派生可以是类和结构体(C#中叫结构),如果继承了一个接口,必须实现他的所有成员,即允许接口声明的方法、属性、事件成员和索引器。一个类只能有一个基类,但可以继承多个接口,并且基类必须要放在所有的接口前面。

对于继承多个接口,如果两个接口中有相同的方法声明,可以实现一个类级别成员对应两个接口中的声明,
也可以使用显示接口成员来分别实现,但是这种方式实现的成员不能被类中内部方法调用,也不能在类外被直接调用,必须转换然后使用对应接口的引用来调用。

对于显示接口成员实现方式,虽然显示实现的方法定义在继承类中,但是属于对应的接口,而不属于类;对于类级别实现的成员方法,同时属于对应的接口和类,更准确说类和接口的同名方法使用了同一份方法(函数)定义。

代码示例:

//主函数
void Main()
{
    //接口1调用自己的显示接口成员实现
    ICustomIfc1 obj1 = new MyClass();
    obj1.PrintOut();

    //接口2没有显示接口成员实现,调的是类级别成员实现
    ICustomIfc2 obj2 = new MyClass();
    obj2.PrintOut();

    //调用类级别实现
    MyClass obj3 = new MyClass();
    obj3.PrintOut();

    //显示强转没什么意义(其实和上面隐式转换一样),调用的还是子类实现接口1的方法
    ICustomIfc1 obj4 = (ICustomIfc1)obj3;
    obj4.PrintOut();

    //显示实现接口成员不能被直接调用,会编译不过,只能转为接口调用
    MyClass obj5 = new MyClass();
    //obj3.Ifc1Fun(); //错误
    ((ICustomIfc1)obj3).Ifc1Fun();
}


namespace Custom
{
    //接口1
    interface ICustomIfc1
    {
    	public void PrintOut();
    	public void Ifc1Fun();
    }

    //接口2
    interface ICustomIfc2
    {
    	public void PrintOut();
    }

    //基类
    class Base
    {
    }

    //派生类继承多个接口
    class MyClass : Base, ICustomIfc1, ICustomIfc2
    {
    	//显示接口成员实现方式
    	//实现接口1的方法,注意前面不能用public修饰,会编译不过
    	void ICustomIfc1.PrintOut()
    	{
    	    Console.WriteLine("实现接口1的方法");
    	}
    	
    	/*
    	//显示实现接口2的方法
    	void ICustomIfc2.PrintOut()
    	{
    	    Console.WriteLine("实现接口2的方法");
    	}
    	*/

    	//类级别成员实现方式,此方法会同时作为两个接口的实现方法
    	public void PrintOut()
    	{
    	    Console.WriteLine("同时实现两个接口的方法");
    	}



    	//显示接口成员实现方式
    	void ICustomIfc1.Ifc1Fun()
    	{
    	    Console.WriteLine("同时实现两个接口的方法");
    	}

    	void Func()
    	{
    	    //显示接口成员实现不能直接被调用,编译不过,只能转为接口调用
    	    //Ifc1Fun(); //错误
    	    ((ICustomIfc1)this).Ifc1Fun(); 
    	}
    }//class
}//namespace

输出:

实现接口1的方法
同时实现两个接口的方法
同时实现两个接口的方法
实现接口1的方法
同时实现两个接口的方法

接口继承其他接口

一个接口可以继承其他的接口,只要把其他的接口放到基接口列表中即可

代码示例:

interface Ifc1
{
    void Fun1();
} 

interface Ifc2
{
    void Fun2();
}

//继承两个接口
interface IMyIfc : Ifc1, Ifc2
{
    void Fun3();
}

//继承接口后,要实现所有接口的方法
class MuClass : IMyIfc
{
    public void Fun1()
    {
    }

    public void Fun2()
    {
    }

    public void Fun3()
    {
    }
}

本文作者:韩白白zz

本文链接:https://www.cnblogs.com/hanbaibai/p/16192555.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   韩白白zz  阅读(111)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.