基类与接口混合继承的声明问题 [C#, Design] -Allen Lee's Magic
2008-05-06 17:34
483 查看
Updated on Friday, November 19, 2004
Written by Allen Lee
1. 问题初现
今天,查看《接口继承的声明问题》一文的反馈,发现Ninputer留下这样一道题:
2. 探索问题 & 理解问题
解决问题的过程既是一个探索的过程也是一个推理论证的过程。OK,下面我尝试用反证法来探索这个问题。
首先,我假设问题中B类的两种继承方式有着一样的效果,并试着寻找它们的不一样。为了了解这两种方式的效果,我把上面代码补充完整:
class Program
interface IC
class A : IC
class Program
interface IC
class A : IC
class B1 : A
class B2 : A, IC
interface IC
class A : IC
class B2 : A, IC
class Program
interface IC
class A : IC
class B1 : A
class B2 : A, IC
class Program
class Program
class AX : A, IC
class B1 : AX
class B2 : AX
class Program
class B2 : A1, IC1
{ }
其中,A1和A2是没有实质的区别的,详细请看《接口继承的声明问题》一文;而B1和B2却在某些场合表现出不同的行为,为何B1和B2会有这种差异,相信现在的你应该有所了解了吧!
7. IL呢?[Updated]
噢,对了,Ninputer的问题还有个“编译器在IL级别是用什么手段实现这个功能的呢?”!如果你看完本文后还嫌不够,希望更加深入了解一下IL层次上,CLR是怎样实现接口重新映射的原理的话,我推荐你阅读《接口映射的实现及原理》。
posted on 2004-11-19 13:12 Allen Lee 阅读(2508) 评论(10) 编辑 收藏 收藏至365Key 所属分类: C#
我其实也在思考这个问题,看到你在分析类似问题就忍不住提了出来,呵呵。因为在孙展波的Blog里,我看到了关于实现接口的方法是不是必须是虚方法的讨论,结果是必须virtual而且必是newslot。我想必须virtual的原因是实现接口其实就是和重写虚方法一样的原理。如果基类已经实现了某接口,原理上是基类已经重写了那个接口中的虚方法。那子类再继承这个基类,就也继承了那个重写过的方法,但同时又让子类实现那个接口,它不就又得重写那个接口中虚方法吗?子类同时拥有两套重写自同一虚方法的代码怎么可以呢?可C#就是允许……(VB是禁止这样语法的)所以实现接口的方法必然有特殊的地方,我觉这就是必须有newslot这个标记的原因,它能中断基类实现接口成员的虚方法表的延续。
为什么实现接口的方法总是virtual和newslot的?现在我这个问题就弄清楚了,呵呵。VB2005正在增加这个特性。 回复
请指教。 回复
正当大家都热烈地拥抱面向对象的继承时,你是否曾经因为继承的某些微妙效果而感到困惑呢?本文将为你解析接口重新实现(Interface re-impletementation)所带来的微妙效果。 回复
有一个interface ABC包括了如下的方法M():
public interface ABC
{
void M();
}
另外有个类Class Class1继承了ABC并且拥有自己的方法N():
public class Class1:ABC
{
public Class1(){}
public void M()
{
Console.WriteLine("Now we are in Class1, using method which inherit from Interface ABC ");
}
public void N()
{
Console.WriteLine(("Now we are in Class1, we used method which not inherit from Interface ABC ");
}
}
程序中有如下语句:
ABC t = new Class1();
t.M();
这种情况下编译可以通过而且会输出正确的结果
但是如果是下面的情况:
ABC t = new Class1();
t.N();
编译就会出错;
所以通过ABC t = new Class1()这句话我们得到的肯定不是Class1的一个实例
但是接口是不可以实例化的
那么ABC t = new Class1()究竟实例化了一个什么东西?
Written by Allen Lee
1. 问题初现
今天,查看《接口继承的声明问题》一文的反馈,发现Ninputer留下这样一道题:
如果有 class A : Interface1 那么 class B : A, Inteface1 和 class B : A 会出现什么不同的情况呢。编译器在IL级别是用什么手段实现这个功能的呢? |
2. 探索问题 & 理解问题
解决问题的过程既是一个探索的过程也是一个推理论证的过程。OK,下面我尝试用反证法来探索这个问题。
首先,我假设问题中B类的两种继承方式有着一样的效果,并试着寻找它们的不一样。为了了解这两种方式的效果,我把上面代码补充完整:
class Program
interface IC
class A : IC
class Program
interface IC
class A : IC
class B1 : A
class B2 : A, IC
interface IC
class A : IC
class B2 : A, IC
class Program
interface IC
class A : IC
class B1 : A
class B2 : A, IC
class Program
class Program
class AX : A, IC
class B1 : AX
class B2 : AX
class Program
class B2 : A1, IC1
{ }
其中,A1和A2是没有实质的区别的,详细请看《接口继承的声明问题》一文;而B1和B2却在某些场合表现出不同的行为,为何B1和B2会有这种差异,相信现在的你应该有所了解了吧!
7. IL呢?[Updated]
噢,对了,Ninputer的问题还有个“编译器在IL级别是用什么手段实现这个功能的呢?”!如果你看完本文后还嫌不够,希望更加深入了解一下IL层次上,CLR是怎样实现接口重新映射的原理的话,我推荐你阅读《接口映射的实现及原理》。
posted on 2004-11-19 13:12 Allen Lee 阅读(2508) 评论(10) 编辑 收藏 收藏至365Key 所属分类: C#
评论
# re: 基类与接口混合继承的声明问题 [C#, Design] 2004-11-17 08:44 Ninputer
Alan Lee,你的文笔实在太好了!而且你分析得也太好了。我其实也在思考这个问题,看到你在分析类似问题就忍不住提了出来,呵呵。因为在孙展波的Blog里,我看到了关于实现接口的方法是不是必须是虚方法的讨论,结果是必须virtual而且必是newslot。我想必须virtual的原因是实现接口其实就是和重写虚方法一样的原理。如果基类已经实现了某接口,原理上是基类已经重写了那个接口中的虚方法。那子类再继承这个基类,就也继承了那个重写过的方法,但同时又让子类实现那个接口,它不就又得重写那个接口中虚方法吗?子类同时拥有两套重写自同一虚方法的代码怎么可以呢?可C#就是允许……(VB是禁止这样语法的)所以实现接口的方法必然有特殊的地方,我觉这就是必须有newslot这个标记的原因,它能中断基类实现接口成员的虚方法表的延续。
为什么实现接口的方法总是virtual和newslot的?现在我这个问题就弄清楚了,呵呵。VB2005正在增加这个特性。 回复
# re: 基类与接口混合继承的声明问题 [C#, Design] 2004-11-17 08:49 Ninputer
天啊,我突然觉得重实现接口是一个难以在VB中实现的特性……因为VB在实现接口上所用的原理和C#不尽相同。 回复# re: 基类与接口混合继承的声明问题 [C#, Design] 2004-11-17 12:42 wayfarer
对。我也看了孙展波的Blog。其实直接实现接口方法的类中,该方法相当于是一个sealed virtual。实现接口方法,可以理解为在类中重写了接口的虚方法。这个方法可以被其派生类继承,但不允许被重写,因为该方法已经被sealed了。如果要在派生类中重写该方法,必须在其父类方法中,添加virtual关键字。否则编译不能通过。 回复# re: 基类与接口混合继承的声明问题 [C#, Design] 2004-11-18 14:05 寒枫天伤
与你的看法...有点不一样...不是这样的.......:( 回复# re: 基类与接口混合继承的声明问题 [C#, Design] 2004-11-18 14:09 Allen Lee
To 寒枫天伤:请指教。 回复
# re: 基类与接口混合继承的声明问题 [C#, Design] 2004-11-18 18:24 寒枫天伤
看http://www.cnblogs.com/william_fire/archive/2004/11/18/65263.html的回复吧 回复# re: 基类与接口混合继承的声明问题 [C#, Design] 2004-11-24 19:03 Allen Lee
点评:正当大家都热烈地拥抱面向对象的继承时,你是否曾经因为继承的某些微妙效果而感到困惑呢?本文将为你解析接口重新实现(Interface re-impletementation)所带来的微妙效果。 回复
# re: 基类与接口混合继承的声明问题 [C#, Design] 2005-09-16 09:06 Anders
呵呵,在父类实现接口方法时在方法前加上virtual,子类override就能达到你的效果了 回复# re: 基类与接口混合继承的声明问题 [C#, Design] 2005-11-24 09:37 xuzicn
Allen Lee我有如下问题需要你的解答:有一个interface ABC包括了如下的方法M():
public interface ABC
{
void M();
}
另外有个类Class Class1继承了ABC并且拥有自己的方法N():
public class Class1:ABC
{
public Class1(){}
public void M()
{
Console.WriteLine("Now we are in Class1, using method which inherit from Interface ABC ");
}
public void N()
{
Console.WriteLine(("Now we are in Class1, we used method which not inherit from Interface ABC ");
}
}
程序中有如下语句:
ABC t = new Class1();
t.M();
这种情况下编译可以通过而且会输出正确的结果
但是如果是下面的情况:
ABC t = new Class1();
t.N();
编译就会出错;
所以通过ABC t = new Class1()这句话我们得到的肯定不是Class1的一个实例
但是接口是不可以实例化的
那么ABC t = new Class1()究竟实例化了一个什么东西?
相关文章推荐
- 基类与接口混合继承的声明问题 [C#, Design]
- 基类与接口混合继承的声明问题 [C#, Design]
- 接口继承的声明问题 [C#, BCL]
- 接口继承的声明问题 [C#, BCL]
- .NET中的泛型、接口、基类、继承混合使用
- 接口继承的声明问题
- 接口继承的声明问题
- 接口继承的声明问题
- 接口和类混合继承的问题
- Java 继承接口同名函数问题
- java中的接口和接口之间的继承问题
- 接口继承中一个常见问题的思考
- 解决继承窗体或用户控件时“visual继承当前被禁用,因为基类引用设备特定的组件或包含 p/invoke”问题(转)
- 添加空白页面后继承自定义类提示错误:声明一定不能指定不同的基类
- 关于“JAVA中为什么没有了多继承并出现了接口”这一问题引发的一些思考
- JAVA 接口与继承作业——动手动脑以及课后实验性问题
- Java小程序---接口中抽象方法的实现(解决了JAVA语言不能多继承的问题)
- 关于继承类的指针指向基类的内存的问题
- 继承和基类的虚函数的访问限制和默认参数值的问题
- c++类继承中的using声明,派生类中用using声明改变基类成员的访问权限[zz]