接口设计方式

自顶向下 (如图所示),自底向上。

接口成员:

事件

  1. public interface IDrawingObject
  2. {
  3. event EventHandler ShapeChanged;
  4. }

 在类中实现接口事件
在类中声明事件,然后在相应区域中调用它

  1. namespace ImplementInterfaceEvents
  2. {
  3. public interface IDrawingObject
  4. {
  5. event EventHandler ShapeChanged;
  6. }
  7. public class MyEventArgs : EventArgs
  8. {
  9. // class members
  10. }
  11. public class Shape : IDrawingObject
  12. {
  13. public event EventHandler ShapeChanged;
  14. void ChangeShape()
  15. {
  16. // Do something here before the event...
  17. OnShapeChanged(new MyEventArgs(/*arguments*/));
  18. }
  19. // or do something here after the event.
  20. }
  21. protected virtual void OnShapeChanged(MyEventArgs e)
  22. {
  23. ShapeChanged?.Invoke(this, e);
  24. }
  25. }

下面的示例演示如何处理不太常见的情况:类继承自两个或多个接口,且每个接口都具有相同名称的事件。 在这
种情况下,你必须为至少其中一个事件提供显式接口实现。 为事件编写显式接口实现时,还必须编写 add 和
remove 事件访问器。 通常这些访问器由编译器提供,但在这种情况下编译器不提供它们。
通过提供自己的访问器,可以指定两个事件是由类中的同一个事件表示,还是由不同事件表示。 例如,如果根据
接口规范应在不同时间引发事件,可以在类中将每个事件与单独实现关联。 在下面的示例中,订阅服务器确定它
们通过将形状引用转换为 IShape 或 IDrawingObject 接收哪个 OnDraw 事件。

  1. namespace{
  2. usingWrapTwoInterfaceEvents
  3. System;
  4. public interface IDrawingObject
  5. {
  6. // Raise this event before drawing
  7. // the object.
  8. // the object.
  9. event EventHandler OnDraw;
  10. }
  11. public interface IShape
  12. {
  13. // Raise this event after drawing
  14. // the shape.
  15. event EventHandler OnDraw;
  16. }
  17. // Base class event publisher inherits two
  18. // interfaces, each with an OnDraw event
  19. public class Shape : IDrawingObject, IShape
  20. {
  21. // Create an event for each interface event
  22. event EventHandler PreDrawEvent;
  23. event EventHandler PostDrawEvent;
  24. object objectLock = new Object();
  25. // Explicit interface implementation required.
  26. // Associate IDrawingObject's event with
  27. // PreDrawEvent
  28. #region IDrawingObjectOnDraw
  29. event EventHandler IDrawingObject.OnDraw
  30. {
  31. add
  32. {
  33. lock (objectLock)
  34. {
  35. PreDrawEvent += value;
  36. }
  37. }
  38. remove
  39. {
  40. lock (objectLock)
  41. {
  42. PreDrawEvent -= value;
  43. }
  44. }
  45. }
  46. #endregion
  47. // Explicit interface implementation required.
  48. // Associate IShape's event with
  49. // PostDrawEvent
  50. event EventHandler IShape.OnDraw
  51. {
  52. add
  53. {
  54. lock (objectLock)
  55. {
  56. PostDrawEvent += value;
  57. }
  58. }
  59. remove
  60. {
  61. lock (objectLock)
  62. {
  63. PostDrawEvent -= value;
  64. }
  65. }
  66. }
  67. // For the sake of simplicity this one method
  68. // implements both interfaces.
  69. public void Draw()
  70. {
  71. // Raise IDrawingObject's event before the object is drawn.
  72. PreDrawEvent?.Invoke(this, EventArgs.Empty);
  73. Console.WriteLine("Drawing a shape.");
  74. // Raise IShape's event after the object is drawn.
  75. PostDrawEvent?.Invoke(this, EventArgs.Empty);
  76. }
  77. }
  78. public class Subscriber1
  79. {
  80. // References the shape object as an IDrawingObject
  81. public Subscriber1(Shape shape)
  82. {
  83. IDrawingObject d = (IDrawingObject)shape;
  84. d.OnDraw += d_OnDraw;
  85. }
  86. void d_OnDraw(object sender, EventArgs e)
  87. {
  88. Console.WriteLine("Sub1 receives the IDrawingObject event.");
  89. }
  90. }
  91. // References the shape object as an IShape
  92. public class Subscriber2
  93. {
  94. public Subscriber2(Shape shape)
  95. {
  96. IShape d = (IShape)shape;
  97. d.OnDraw += d_OnDraw;
  98. }
  99. }
  100. void d_OnDraw(object sender, EventArgs e)
  101. {
  102. Console.WriteLine("Sub2 receives the IShape event.");
  103. }
  104. public class Program
  105. {
  106. static void Main(string[] args)
  107. {
  108. Shape shape = new Shape();
  109. Subscriber1 sub = new Subscriber1(shape);
  110. Subscriber2 sub2 = new Subscriber2(shape);
  111. shape.Draw();
  112. // Keep the console window open in debug mode.
  113. System.Console.WriteLine("Press any key to exit.");
  114. System.Console.ReadKey();
  115. }
  116. }
  117. }
  118. /* Output:
  119. Sub1 receives the IDrawingObject event.
  120. Drawing a shape.
  121. Sub2 receives the IShape event.
  122. */

C# InterFace 接口的更多相关文章

  1. as3.0 interface接口使用方法

    [转]as3.0 interface接口使用方法 AS在2.0的时候就支持接口了 接口能够让你的程序更具扩展性和灵活性,打个例如 比方你定义了一个方法 代码: public function aMet ...

  2. interface接口

    当一个抽象类中的方法都是抽象的时候,这时可以将该抽象类用另一种形式定义和表示,就是接口 interface. 定义接口使用的关键字不是class,是interface.接口中常见的成员: 这些成员都有 ...

  3. golang面向对象和interface接口

    一. golang面向对象介绍 1.golang也支持面向对象编程,但是和传统的面向对象编程有区别,并不是纯粹的面向对象语言.2.golang没有类(class),golang语言的结合体(struc ...

  4. Golang 入门系列(四)如何理解interface接口

    前面讲了很多Go 语言的基础知识,包括go环境的安装,go语言的语法等,感兴趣的朋友,可以先看看之前的文章.https://www.cnblogs.com/zhangweizhong/category ...

  5. go interface接口

    一:接口概要 接口是一种重要的类型,他是一组确定的方法集合. 一个接口变量可以存储任何实现了接口方法的具体值.一个重要的例子就是io.Reader和io.Writer type Reader inte ...

  6. java interface接口的传值方法

    A 类 package interface_test; public class A { private IPresenter ip; public A(IPresenter ip) { this.i ...

  7. JAVA 构造器, extends[继承], implements[实现], Interface[接口], reflect[反射], clone[克隆], final, static, abstrac

    记录一下: 构造器[构造函数]: 在java中如果用户编写类的时候没有提供构造函数,那么编译器会自动提供一个默认构造函数.它会把所有的实例字段设置为默认值:所有的数字变量初始化为0;所有的布尔变量设置 ...

  8. 011-对象——interface接口说明与使用方式实例

    <?php /** interface接口说明与使用方式实例 * * 接口里面的方法全是抽象方法,没有实体的方法.这样的类我们就叫做接口.定义的时候用Interface定义.实现接口时用impl ...

  9. Java Interface接口

    Java 中接口概念 接口可以理解为一种特殊的 类,由 全局常量 和 公共的抽象方法 所组成. 类是一种具体实现体,而接口定义了某一批类所需要遵循的规范,接口不关心这些类的内部数据, 也不关心这些类里 ...

  10. Golang基础(8):go interface接口

    一:接口概要 接口是一种重要的类型,他是一组确定的方法集合. 一个接口变量可以存储任何实现了接口方法的具体值.一个重要的例子就是io.Reader和io.Writer type Reader inte ...

随机推荐

  1. 申请Namecheap的.me 顶级域名以及申请ssl认证--github教育礼包之namecheap

    关于教育礼包的取得见另一篇随笔,在那里笔者申请了digital ocean的vps(虚拟专用主机),跟阿里云差不多,不过个人感觉比阿里云便宜好用一点. 有了自己的主机ip,就想到申请域名,方便好记,也 ...

  2. 很详细的FFT(快速傅里叶变换)概念与实现

    FFT 首先要说明一个误区,很多人认为FFT只是用来处理多项式乘的,其实FFT是用来实现多项式的系数表示法和点值表示法的快速转换的,所以FFT的用处远不止多项式乘. FFT的前置知识:点值表示法,复数 ...

  3. Kubernetes 微服务最佳实践

    本文由个人笔记 ryan4yin/knowledge 整理而来 本文主要介绍我个人在使用 Kubernetes 的过程中,总结出的一套「Kubernetes 配置」,是我个人的「最佳实践」. 其中大部 ...

  4. web前端基础之SCC(定位-z-index模态框)

    目录 一:定位(position) 1.relative(相对定位) 2.absolute(绝对定位) 3.fixed(固定) 二:相对定位 1.相对定位 2.实现相对定位 三:绝对定位 1.实现绝对 ...

  5. Open虚拟专用网络

    目录 一:OpenVPN虚拟网络专用 1.简介: 2.OpenVPN的作用 3.远程访问VPN服务 4.OpenVPN两种类型的VPN体系结构 5.全面解析OpenVPN执行流程 6.Openvpn定 ...

  6. pycharm 安装插件

    1.使用pip安装插件 pip安装指定版本的插件: pip install openpyxl==2.6.2 -i https://pypi.doubanio.com/simple/ -i后面跟的是&q ...

  7. Sweetalert模态对话框与Swiper轮播插件、Bootstrap样式组件、AdminLTE后台管理模板地址

    Sweetalert纯JS模态对话框插件地址:http://mishengqiang.com/sweetalert/ AdminLTE后台管理模板系统地址(基于Bootstrap):https://a ...

  8. 如何定制docker容器的系统时间

    Dockerfile加入下面一句(标红的部分): FROM xxxxxxENV JAVA_OPTS="-Dfile.encoding=UTF-8"ENV TZ=Asia/Shang ...

  9. 剑指Offer系列_30_包含min函数的栈

    以空间换时间: package leetcode.sword_to_offfer.day01; import java.util.Stack; /** * 定义栈的数据结构,请在该类型中实现一个能够得 ...

  10. Java数据库连接池--DBCP浅析.

    一. 为何要使用数据库连接池假设网站一天有很大的访问量,数据库服务器就需要为每次连接创建一次数据库连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出.拓机.数据库连接是一种关键的有限的昂贵 ...