首页 新闻 会员 周边

问个很不该问的问题。

0
悬赏园豆:20 [已解决问题] 解决于 2008-01-30 16:10
<P>&nbsp;&nbsp;&nbsp; public interface BaseClass<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string testA();<BR>&nbsp;&nbsp;&nbsp; }</P> <P>&nbsp;&nbsp;&nbsp; public class ClassA : BaseClass<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public string testA() <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "testA";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }</P> <P>&nbsp;&nbsp;&nbsp; public interface BaseTest <BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BaseClass test();<BR>&nbsp;&nbsp;&nbsp; }</P> <P>&nbsp;&nbsp;&nbsp; public class TestA : BaseTest <BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public ClassA test()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }</P> <P>这样为什么编译通不过。。</P>
Randy0528的主页 Randy0528 | 初学一级 | 园豆:41
提问于:2008-01-24 11:13
< >
分享
最佳答案
0
编译不过的原因很明显,编译器已经给出了明确的解释,我想lz是不是想问编译器问什么不支持这种方式? 1、从OO的角度来看这个问题,BaseClass作为基类,它可以统一指代所有子类,这就是所谓的【多态】而已,所以从实际应用的角度来说,lz的这种用法本身就没有太大意义,正确的写法是: public class TestA : BaseTest { public BaseClass test() { return ClassA的实例 ; } } 2、从更进一步深入OO语义的角度来说,你可以说ClassA IS A BaseClass ,但是不能说 BaseClass IS A ClassA,也就是说因为子类会对基类进行扩展,基类永远都是子类的一个子集,使用基类公开的接口来访问子类的实例是不会发生任何问题的,而子类却很可能是基类的超集,也就是说,不能通过子类去访问基类的实例,存在运行时异常的风险!这也是【继承】的重要特性,简单地说,基类可以作为所有子类的代表给对外交互,而子类不能代表基类!
Justin | 小虾三级 |园豆:980 | 2008-01-24 12:51
其他回答(3)
0
'ClassLibrary1.TestA' does not implement interface member 'ClassLibrary1.BaseTest.test()'. 'ClassLibrary1.TestA.test()' cannot implement 'ClassLibrary1.BaseTest.test()' because it does not have the matching return type of 'ClassLibrary1.BaseClass'. 返回类型不匹配. TestA.test() 只能返回声明为 public BaseClass test() 才行. 或者,也可以使用范型: public interface BaseTest<T> where T: BaseClass { T test(); } public class TestA : BaseTest<ClassA> { ClassA BaseTest<ClassA>.test() { return null; } }
deerchao | 园豆:8367 (大侠五级) | 2008-01-24 11:46
0
这是面向对象中Override的基本规则。子类Override父类方法时,签名必须严格一致(包括:函数名,参数类型,返回类型) 楼上给出了两个解决方案。 ×修改子类签名,以符合上面的原则。 (但是,子类中使用ClassA比较难受) ×修改父类签名,使用泛型。从而使子类可以继承特定类型。(但是可能TestA类型和TestB类型没有一个共同的基类,复用性不好) 还有一个解决方案,使用interface的显示实现。如下: public class TestA : BaseTest { public ClassA test() { return null; } BaseClass BaseTest.test() { return test(); } } 哈哈,如果是我,我认为比较完美的解决方案如下: public interface ITest { BaseClass test(); } public class BaseTest<T> : ITest where T : BaseClass { BaseClass ITest.test() { return this.test(); } public virtual T test() { return default(T); } } public class TestA : BaseTest<ClassA> {} public class TestB : BaseTest<ClassB> {}
Colin Han | 园豆:3041 (老鸟四级) | 2008-01-24 12:44
0
你在接口 BaseTest 里声明的是接口BaseClass 而在实现接口BaseTest 的TestA 中给出的是ClassA ClassA只是一个实现了接口BaseClass的类,就好比我声明了要食物,你却只给土豆,那么我要其他食物的时候你就没办法了
XXXCccddd | 园豆:40 (初学一级) | 2008-01-25 08:15
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册