C#学习笔记8:接口、委托、事件

今日继续我的C#学习之路,今日学习接口、委托、事件,文章从实践出发学习这三个设计理念,并提供完整源码

目录

1、接口(多重继承):

代码:

运行结果:

2、委托(方法的代理/函数指针):

创建控制台程序实现委托:

遇到的报错及解决:

修改后的代码:

运行结果:

3、事件:

 定义事件:

创建控制台程序,假设一个热水器

代码:

运行结果:


1、接口(多重继承):

C#不支持类的多重继承,但可以继承多个接口

C#中的多重继承要用接口来实现,接口就是为了实现多继承而产生的,

C#中,接口可多继承,接口之间可互相继承,普通类和抽象类可以继承自接口,一个类可以同时继承一个类和多个接口,但是接口不能继承类

(1)接口名是任意合法的标识符,建议以大写I开头。
(2)声明的接口可以继承一个基类和多个其他接口。
(3)接口修饰符可以是new、public、protected、internal、private。
(4)接口成员前面不允许有修饰符,都默认为公有成员。
(5)接口成员可以分为四类-方法、属性、事件和索引器,而不能包含成员变量

(6)不能在声明接口的同时编写接口成员的实现代码。 

接口要通过继承才能实现,即定义继承接口的类,并在类中实现所有的接口成员

class 类名:[基类名],接口名1,接口名2...
{
    类成员
}

定义的类必须提供被继承接口中所有成员的实现,否则将产出编译错误

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Ipoint_YZH
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //应用接口的派生类Point实例化一个新的对象并进行初始化赋值
            Point p = new Point(5,30);
            Console.WriteLine("创建的点坐标是:x={0},y={1}\n",p.x,p.y);
            Console.ReadLine();
        }
        public interface IPoint
        {
            int x { get; set; }//定义属性成员x,他含有读写的抽象访问
            int y { get; set; }//定义属性成员y,他含有读写的抽象访问
        }
        class Point:IPoint
        {
            //定义俩个类内部访问的私有成员变量
            private int px;
            private int py;

            //构造函数实现类初始化,为私有变量赋值
            public Point (int x,int y)
            {
                px = x;
                py = y;

            }

            //接口属性x实现
            public int x
            {
                get { return px; }//实现读访问
                set { px = value; }//实现写访问
            }
            //接口属性y实现
            public int y
            {
                get { return py; }//实现读访问
                set { py = value; }//实现写访问
            }

        }


    }
}

运行结果:

2、委托(方法的代理/函数指针):

委托是C#特有的功能,也翻译为代理、代表、指代

C#中没指针的概念,但通过委托可以实现C/C++中函数指针的功能,且比函数指针更强

方法的委托就是方法的别名(或叫方法的代理)

通过委托不仅能执行方法,还能将方法传到其他方法中,实现方法回调等。

 能被委托的方法必须是在运行时为内存中已经确定的方法,如静态方法、对象的方法,而类的非静态方法(没实例化)是不能被委托的;

定义委托格式语法如下:

其中属性、修饰符可选(new、public、internal、protected、private)

属性 修饰符 delegate 返回类型 委托类型名(参数列表);
public delegate void Delegate1();
public delegate int Delegate2(string s);
public delegate string Delegate3(int i,int j);

委托的实例化:

委托对象 = new 委托类型(关联方法);
//创建委托对象fd,它关联对象a的方法f()
MyDelegate fd=new MyDelegate(a.f);

//这句关联A的静态方法g()
MyDelegate gd=new MyDelegate(A.g);

创建控制台程序实现委托:

遇到的报错及解决:

严重性    代码    说明    项目    文件    行    禁止显示状态
错误    CS0236    字段初始值设定项无法引用非静态字段、方法或属性“Program.B.mdh”    Weituo    D:\visualstudioWorkstation\Weituo\Weituo\Program.cs    32    活动

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Weituo
{
    internal class Program
    {
        public delegate int myDelegateHandler(int a,int b);
        static void Main(string[] args)
        {

        }

        public class A
        {
            //静态的处理方法,返回俩数相加之和
            public static int M1(int a, int b)
            {
                int c = a + b;
                return c;
            }
        }

        public class B 
        {
            //实例一个委托
            myDelegateHandler mdh = new myDelegateHandler(A.M1);
            //调用委托
            int sum = mdh(1, 2);

        }

    }
}

问题出在框出的位置:

修改后的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Weituo
{
    internal class Program
    {
        public delegate int myDelegateHandler(int a,int b);

        public class A
        {
            //静态的处理方法,返回俩数相加之和
            public static int M1(int a, int b)
            {
                int c = a + b;
                return c;
            }
        }

        public class B 
        {
            static void Main(string[] args)
            {
                //实例一个委托
                myDelegateHandler mdh = new myDelegateHandler(A.M1);
                //调用委托
                int sum = mdh(1, 2);
                Console.WriteLine(sum);
                Console.ReadLine();
            }
        }

    }
}

运行结果:

3、事件:

事件是 C#中的一个高级概念,是操作发生时允许执行特定应用程序的代码机制。

事件要么在相关联的操作发生前发生(事前事件),要么在操作发生后发生(事后事件)。

当用户单击窗口中的按钮时,将引发一个事后事件,以允许执行特定于应用程序的方法。

类或对象可以通过事件向其他类或对象通知发生的相关事件。

发送(或引发)事件的类称为“发行者”,接收(或处理)事件的类称为“订户”。

在典型的 C# Windows窗体或 Web应用程序中,可以订阅由控件(如按钮盒列表框)引发的事件,“学生开始答卷”是这个事件引发的动作,老师是事件的发行者,学生是事件的订户。

 定义事件:

[访问修饰符]event 委托名 事件名;
//定义事件eventMe
public delegate void delegateMe();
private event delegateMe eventMe; 

在C#类中定义和使用事件一般有以下几个步骤:

//(1)在一个类中声明关于事件的委托
public delegate void 事件类型名称(object sender,EventArgs e);

//(2)在类中声明事件,使用步骤(1)中的delegate作为事件类型
public event 事件类型名称 事件名称

//(3)在类中需要引发事件的方法中,编写引发事件的方法
事件名称(this,new EventArgs());
//或者
if(事件名称!=null) 事件名称(this,new EventArgs());

//(4)订阅事件,当事件发生时通知订户
带有事件类型的实例.事件名称 +=new 事件名称(事件处理方法名称);

//(5)编写事件处理方法
public void 事件处理方法名称(object sender,EventArgs e);
    {
        //代码
    }

//(6)适当条件下触发事件,调用步骤(3)中引发事件的方法

创建控制台程序,假设一个热水器

当通电加热到水温超过96℃时,扬声器会发出语音告诉你水的温度,

液晶屏显示水温的变化,提示水快开了。

定义一个类来代表热水器的类 Heater,其中有

代表水温的字段temperature

有给水加热的BoilWaterO方法

发出语音报警的 MakeAlertO方法

显示水温的ShowMsgO方法

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace shijian_reshuiqi
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Heater heater = new Heater();//创建热水器对象heater
            Alarm alarm = new Alarm();//创建报警器对象alarm
            heater.BoilEvent += alarm.MakeAlert;//给alarm类的MakeAlert方法订阅事件
            heater.BoilEvent += Display.ShowMsg;//给Display类的 ShowMsg静态方法订阅事件
            heater.BoilWater();//烧水
            Console.ReadLine();
        }
        //Heater热水器类
        public class Heater
        {
            private int temperature;//声明表面当前水温字段
            public delegate void BoilHandler(int param);//声明关于事件的委托
            public event BoilHandler BoilEvent;//声明水要烧开的事件

            public void BoilWater()//烧水的方法
            {
                for (int i=0;i<=100;i++)//水温超过96,引发事件BoilEvent
                {
                    temperature = i;
                    if(temperature>96)
                    {
                        if(BoilEvent!=null)
                        {
                            BoilEvent(temperature);//调用所有订阅对象的方法
                        }
                    }
                }
            }

        }

        public class Alarm //定义Alarm警报
        {
            public void MakeAlert(int param)
            {
                Console.WriteLine("提示:水已经{0}度了", param);
            }
        }

        public class Display//显示水温的类
        {
            public static void ShowMsg(int param)
            {
                Console.WriteLine("Display:s水快烧开了,当前温度:{0}度",param);
            }
        }


    }
}

运行结果:

相关推荐

  1. C# 系统学习事件委托

    2024-04-06 22:44:03       15 阅读
  2. C# 委托/事件/lambda

    2024-04-06 22:44:03       42 阅读
  3. C#委托事件

    2024-04-06 22:44:03       17 阅读
  4. C# 委托事件

    2024-04-06 22:44:03       18 阅读
  5. C# - 委托事件

    2024-04-06 22:44:03       7 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-06 22:44:03       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-06 22:44:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-06 22:44:03       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-06 22:44:03       20 阅读

热门阅读

  1. c++运算符大全

    2024-04-06 22:44:03       21 阅读
  2. html基础介绍

    2024-04-06 22:44:03       13 阅读
  3. windows渗透信息收集

    2024-04-06 22:44:03       17 阅读
  4. ES6 都有什么 Iterator 遍历器

    2024-04-06 22:44:03       15 阅读
  5. 【SecretFlow——SPU进阶】

    2024-04-06 22:44:03       14 阅读
  6. 【00150】2024 金融理论与实务试卷一

    2024-04-06 22:44:03       17 阅读
  7. Windows安装SSH超详细教程

    2024-04-06 22:44:03       19 阅读
  8. 力扣-简化路径

    2024-04-06 22:44:03       17 阅读
  9. 【数据结构】顺序表与链表

    2024-04-06 22:44:03       14 阅读