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

[C#学习笔记]接口的特性与用法

视频地址:一期视频看透C#接口的全部特性及用法_哔哩哔哩_bilibili

强烈推荐学习C#和WPF的朋友关注此UP,知识点巨多,讲解透彻!

一、总览

public interface IOverall
{
    /// <summary>
    /// 最普通的方法
    /// </summary>
    void Foo();

    /// <summary>
    /// 属性
    /// </summary>
    string Name { get;set; }

    /// <summary>
    /// 索引器
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    int this[int index] { get; set; }

    /// <summary>
    /// 事件
    /// </summary>
    event EventHandler OnNameChanged;

    /// <summary>
    /// 带默认实现的方法
    /// </summary>
    void Bar() => Console.WriteLine("Bar");

    /// <summary>
    /// 私有方法(需要带默认实现)
    /// </summary>
    private void NonPublicMethod1() => Console.WriteLine("Private");

    /// <summary>
    /// 受保护方法(需要带默认实现,或者可以不实现,继承后实现)
    /// </summary>
    protected void NonPublicMethod2() => Console.WriteLine("Protected");

    /// <summary>
    /// 静态方法(需要带默认实现)
    /// </summary>
    static void StaticMethod() => Console.WriteLine("Static");

    /// <summary>
    /// 抽象静态方法
    /// </summary>
    static abstract void AbstractStaticMethod();

    /// <summary>
    /// 静态虚方法(需要带默认实现)
    /// </summary>
    static virtual void VirtualStaticMethod() => Console.WriteLine("Virtual Static");
}

二、带默认实现的方法

C# 8.0引入

如果接口的方法提供了一个默认实现,那么实现该接口的类可以不实现此方法。

如果实现了此方法,则会覆盖接口中的默认实现,可以理解为接口中带默认实现的方法其实是virtual,而类中的如果实现了此方法,其实是override。

2.1 用法

参考以下代码:

Test test = new Test();
((IFoo1)test).Foo1();
((IFoo1)test).Foo2();

public interface IFoo1
{	
	void Foo1()
	{
		$"这是{nameof(IFoo1)}中{nameof(Foo1)}的默认实现".Dump();
	}

	void Foo2()
	{
		$"这是{nameof(IFoo1)}中{nameof(Foo2)}的默认实现".Dump();
	}
}

class Test : IFoo1
{	
	public void Foo1()
	{
		$"这是{nameof(Test)}中{nameof(Foo1)}的实际实现".Dump();
	}
}

输出结果为

这是Test中Foo1的实际实现
这是IFoo1中Foo2的默认实现

对于带默认实现的方法,如果类中不实现此方法,调用时需要先将类转换成接口,再调接口上的方法,参考以下代码:

Test test = new Test();
((IFoo1)test).Foo1();
((IFoo2)test).Foo1();

public interface IFoo1
{
	void Foo1()
	{
		$"这是{nameof(IFoo1)}中{nameof(Foo1)}的默认实现".Dump();
	}
}

public interface IFoo2
{
	void Foo1()
	{
		$"这是{nameof(IFoo2)}中{nameof(Foo1)}的默认实现".Dump();
	}
}

class Test : IFoo1,IFoo2
{	
	
}

接口IFoo1和IFoo2都有一个带默认实现的方法,且名称相同,类Test实现了IFoo1和IFoo2,如果直接能访问到接口中的方法Foo1,就会造成冲突。

2.2 应用场景

在不破坏影响已有实现的情况下,可以添加新成员。这解决了在第三方已经大量使用了的接口上进行扩展带来问题的痛点。

2.3 private,带默认实现的方法

只能在接口内调用,子接口,实现接口的类中不可访问,参考以下代码

Test test = new Test();
((IFoo1)test).Foo1();

public interface IFoo1
{	
	void Foo1()
	{
		Foo2();
	}

	private void Foo2()
	{
		$"这是{nameof(IFoo1)}中{nameof(Foo2)}的默认实现".Dump();
	}
}

class Test : IFoo1
{	
	
}

2.4 protected,带默认实现的方法

可以在子接口中调用或者覆盖,实现接口的类不可访问

参考以下代码:


Test1 test1 = new Test1();
((IFoo2)test1).Foo2();
((IFoo3)test1).Foo2();

public interface IFoo1
{	
	protected void Foo1()
	{
		$"这是{nameof(IFoo1)}中{nameof(Foo1)}的默认实现".Dump();
	}
}

public interface IFoo2 : IFoo1
{
	void Foo2()
	{
		Foo1();
	}
}

public interface IFoo3 : IFoo1
{
	void Foo2()
	{
		Foo1();
	}
	
	new void Foo1()
	{
		$"这是{nameof(IFoo3)}中{nameof(Foo1)}的默认实现".Dump();
	}
}

class Test1:IFoo2,IFoo3
{
}

运行结果

这是IFoo1中Foo1的默认实现
这是IFoo3中Foo1的默认实现

2.5 Static,带默认实现的方法

静态方法一般用于处理泛型类

参考以下代码:

var student = IDeserializable<Student>.Deserialize("{\"Id\":42,\"Name\":\"Jack\"}");
student.Dump();

interface IDeserializable<T> 
{
	static T? Deserialize(string json) => JsonSerializer.Deserialize<T>(json);
}

class Student : IDeserializable<Student>
{
	public int Id	{get;set;}
	
	public string Name { get; set; }
}

运行结果:

三、static abstract,抽象静态方法

在接口可不实现,实现此接口的类必须要实现此方法

应用场景:

3.1 约束子类具有方法Deserializable,实现序列化功能

interface IDeserializable<T>
{
    static abstract T Deserializable(string json);
}

class MyDataModel : IDeserializable<MyDataModel>
{
    public static MyDataModel Deserializable(string json)
    {
        return JsonSerializer.Deserialize<MyDataModel>(json);
    }
}

3.2 如工厂类中具有方法Create,提供创建功能

    interface IFactory<T>
    {
        static abstract T Create();
    }

    class ClassToBeCreated
    {

    }

    class ClassWithFactoryMethod : IFactory<ClassToBeCreated>
    {
        public static ClassToBeCreated Create()
        {
            return new ClassToBeCreated();
        }
    }

3.3 约束子类实现静态单例

    interface ISingleton<T> where T : ISingleton<T>
    {
        static abstract T Instance { get; }
    }

    class SingletonClass : ISingleton<SingletonClass>
    {
        private static readonly Lazy<SingletonClass> instanceHolder = new Lazy<SingletonClass>();
        public static SingletonClass Instance => instanceHolder.Value;
    }

3.4 逻辑运算法,提供自定义逻辑运算

 interface IOperators<T> where T : IOperators<T>
 {
     static abstract T operator +(T left, T right);
     static abstract T operator -(T left, T right);
 }

 class MyNumber : IOperators<MyNumber>
 {
     public int Value { get; }

     public MyNumber(int value)
     {
         Value = value;
     }

     public static MyNumber operator +(MyNumber left, MyNumber right)
     {
         return new MyNumber(left.Value + right.Value);
     }

     public static MyNumber operator -(MyNumber left, MyNumber right)
     {
         return new MyNumber(left.Value - right.Value);
     }
 }

四、static virtual 静态虚方法

通常用于泛型调用的场合

特性:

1.子类如果未实现具体方法,调用时调用接口中的方法

2.子类如果实现具体方法,调用时调用子类中的方法

代码:

TestCallerInstance(new A());
TestCallerInstance(new B());
ITestInterfaceGenric<A>.TestCallerGeneric();
ITestInterfaceGenric<B>.TestCallerGeneric();

static void TestCallerInstance<T>(T t) where T : ITestInterface
{
    Console.WriteLine(T.TestString1());
}

public interface ITestInterface
{
    static virtual string TestString1()
    {
        return "TestString1 ITestInterface";
    }
}

public interface ITestInterfaceGenric<TSelf> where TSelf : ITestInterfaceGenric<TSelf>
{
    public static void TestCallerGeneric()
    {
        Console.WriteLine(TSelf.TestString2());
    }

    static virtual string TestString2()
    {
        return "TestString2 ITestInterfaceGeneric";
    }
}

public class A : ITestInterface, ITestInterfaceGenric<A>
{
    public static string TestString2()
    {
        return "TestString A";
    }
}

public class B : ITestInterface, ITestInterfaceGenric<B>
{
    public static string TestString1()
    {
        return "TestString1 ITestInterface B";
    }
}


运行结果:

TestString1 ITestInterface
TestString1 ITestInterface B
TestString A
TestString2 ITestInterfaceGeneric


http://www.kler.cn/a/303715.html

相关文章:

  • 使用 VS Code 远程连接时解决 OpenSSL 版本不匹配及权限问题
  • Suricata
  • Mac 使用mac 原生工具将mp4视频文件提取其中的 mp3 音频文件
  • ABAP关于PS模块CJ20N中项目物料的屏幕和字段增强CI_RSADD
  • 如何在CentOS 7上搭建SMB服务
  • React中 修改 html字符串 中某些元素的属性
  • OceanBase 基于企业版本OAT安装与OMS安装与InfluxDB的集成
  • Spring Boot 框架下的房屋租赁业务创新
  • react 组件化开发_生命周期_表单处理
  • 【python2C】1. 输入 (补)
  • Ai产品经理
  • 网络搜索记录会被监控吗?一文带你看懂【打工人必看】
  • 新书速览|循序渐进Vue.js 3.x前端开发实践
  • 上海证券交易所特定参与者接口规格说明书(托管银行卷)1.35 版
  • GitHub Copilot Issue in Visual Studio Code “Status Ready (disabled)“
  • SpringBoot开发——整合Redis
  • 鸿蒙NEXT(API 12)【蓝牙设置】 网络开发
  • 基于SpringBoot+Vue+MySQL的笔记记录分享网站
  • “阡陌云旅”黄河九省文化旅游平台
  • solidity-19-fallback
  • LeetCode之二叉搜索树
  • uniapp登录页面( 适配:pc、小程序、h5)
  • Leetcode面试经典150题-349.两个数组的交集
  • 设计模式 -- 单例设计模式
  • 新能源汽车 BMS 学习笔记篇—BMS 基本定义及分类
  • Kubernetes+Minio+Velero:终极备份解决方案