C#接口回调实现方式(二)
2、方式二:独立接口内部类实现的接口回调
设定场景描述见上一篇博文,实现同样的功能,不同的是两个窗体类MainFrm和CallFrm在定义时完全没有了相互依赖的关系,做到彻底脱钩
(1)该方式使用了独立的接口
public interface MyInterface
{
void CallBackString(string s);
}
}
(2)MainFrm窗体类不再继承接口,而是增加了继承自以上接口的内部类,目的是为运行时向CallFrm传递实现接口的引用。具体见代码
public partial class MainFrm : Form
{
public static MainFrm mainfrm;//定义一个本窗体静态变量,为使内部类能够调用该窗体的控件
public MainFrm()
{
InitializeComponent();
mainfrm = this;//将实例化的本窗体赋值给静态变量mainfrm,便于在内部类中调用该窗体控件时有明确的指向
//原因是在内部类BackClass中的this只的是BackClass对象而不是MainFrm对象
//这里需要重点理解!!!
}
public class BackClass : MyInterface//申明一个实现接口的内部类
{
public void CallBackString(string s)//在内部类中实现接口
{
mainfrm.richTextBox1.Text=s;
}
}
private void btnInput_Click(object sender, EventArgs e)
{
CallFrm f = new CallFrm();//实例化CallFrm
f.SetOnListener(new BackClass());//将实现了接口的内部类实例化后并赋值给CallFrm对象f,
//让在CallFrm对象f中当触发该接口变量的方法时,
//执行内部类BackClass中实现的方法而实现接口回调
f.Show();
}
}
(3)CallFrm窗体类;定义了一个接口类型的变量,并添加了一个设置接口类型变量值的方法,以便调用时实现接口方法的引用的传入
public partial class CallFrm : Form
{
public CallFrm()
{
InitializeComponent();
}
public MyInterface OnListener;//定义一个接口变量
public void SetOnListener(MyInterface onlistener) {//这个方法对接口变量赋值
this.OnListener = onlistener;
}
private void btnOK_Click(object sender, EventArgs e)
{
if (this.OnListener != null)//如果OnListener有实现方法的话
{
this.OnListener.CallBackString(richTextBox1.Text);//就调用该方法
}
this.Close();
}
}
这种方式实现了两个窗体类的彻底解耦,该思路在各种编程环境下应用较多。也是接口回调推荐的思路及用法
在其他的语言中基本也是按照这种思路,比如在java或Android中我们常常看到这种回调的写法,
//Android代码
Print pr=new Print(2,"sd");
pr.setListener(new Print.onListener() {
@Override
public void OnListener(int code, String msg) {
int a=5;
}
});
以上代码的
new Print.onListener() {
@Override
public void OnListener(int code, String msg) {
int a=5;
}
}
这一部分,就相当于我们在C#中的内部类实例化,即等同于new BackClass()。只是C#不支持这样的语法结构,所以用一个内部类实现了相同的效果