c#继承接口方法可以是protected的嘛?
你看到的这两个图,叫做“元数据”,并不是完整的类定义。IController接口声明了Execute方法,那么在ControllerBase抽象类中可以实现,也可以不实现(不实现的话就必须在非抽象子类中实现),但肯定不会以protected方式“实现”,否则,接口就不能被其他类访问,也就不称其为接口了。所以你看到的那个protected并不是对IController接口的实现,只是ControllerBase自己的一个方法而已。所以你可以认为,ControllerBase抽象类并没有实现Execute方法,这个任务交给可以实例化的继承类去实现了。
但如果要深入一步的话,可以看看ControllerBase反编译后的代码,你会发现IController接口的Execute方法在ControllerBase里其实是有实现的,只不过在元数据里看不出来,它是一个针对IController接口的显示声明,形如:
void IController.Execute(RequestContext requestContext)
{
this.Execute(requestContext);
}
这里的this.Execute(requestContext),正是你看到的那个protected方法。这样绕来绕去做有什么意义呢?给你举个例子,你也可以自己试一下:
假设你有两个控制器:HomeController和MyController,你在MyController的Index方法中写入下面的代码:
public ActionResult Index()
{
HomeController a = new HomeController();
a.Execute(ControllerContext.RequestContext);
return View();
}
你会发现根本无法编译,HomeController不是继承自ControllerBase,应当实现IController接口吗?现在你改变一下代码:
public ActionResult Index()
{
IController a = new HomeController();
a.Execute(ControllerContext.RequestContext);
return View();
}
这下可以编译了,说明什么问题呢?还可以再改变一下:
public ActionResult Index()
{
this.Execute(ControllerContext.RequestContext);
return View();
}
还是可以的,现在可以得出结论了:
IController接口既然被抽象类ControllerBase标明现实,那就必须要最终实现的,但是未必要在抽象类内部就实现。
但是ControllerBase确实实现了IController接口,这个现实的意义在于,要求每个非抽象子类实现自己的Execute方法,还不允许用户从该子类的实例直接调用IController接口的方法,而必须通过IController接口来调用。
这样的用法其实在项目中还是挺多的,当你想暴露一个接口,但是仅仅希望实现该接口的类被作为接口时,该方法才显现出来,那么上述方法就是一个很不错的实现。
但是实际中,我试了下,为啥,抽象类继承了接口,不实现其中的方法会报错(可以抽象实现)
我说的“不实现”就是指仅仅抽象实现,的确欠考虑,不好意思。