今日继续我的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方法文章来源:https://www.toymoban.com/news/detail-852358.html
代码:
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);
}
}
}
}
运行结果:
文章来源地址https://www.toymoban.com/news/detail-852358.html
到了这里,关于C#学习笔记8:接口、委托、事件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!