思路参照 http://www.cnblogs.com/allenlooplee/archive/2004/11/16/64553.html,对原文进行了简化和补充,感谢原作者。

问题很简单,如下所示:

有如下接口声明:

     interface IC
{
void M();
}

类A实现了接口IC:

     class A : IC
{
public void M()
{
Console.WriteLine("In class A");
}
}

那么问题来了,如下两种声明类B的方式有什么区别:

     class B : A
{ }
     class B : A, IC
{ }

这个问题,我一直没弄明白,只好写一段代码来验证。

首先,对继承自A类的B进行改造,如下所示:

     class B : A
{
void M()
{
Console.WriteLine("In class B");
}
}

结果编译器出现如下提示:

好吧,将代码改为:

     class B : A
{
public new void M()
{
Console.WriteLine("In class B");
}
}

结果运行后结果竟然是In class A。。。

那下面这样行不行呢?

     class B : A
{
void IC.M()
{
Console.WriteLine("In class B");
}
}

结果这回,编译器直接报错了。。。

好吧,看来,直接继承自A的类B,是无法修改M的行为的。下面来看另外一种方式实现的B。

     class B : A, IC
{
public new void M()
{
Console.WriteLine("In class B");
}
}

运行结果如下图所示:

好了,这回没问题,同样,按照下面这种方式来写,结果也正常:

     class B : A, IC
{
void IC.M()
{
Console.WriteLine("In class B");
}
}

所以,结论就很明显了。
1、如果B仅继承自A,那么接口的方法定就无法在B中被修改。

2、如果B同时继承自A和接口,那么可以在B中实现自己的方法。

其实,上述结论1中,还不算是太准确,有一种方法可以在B中实现自己的方法定义,如下所示:

首先,修改方法A:

     class A : IC
{
public virtual void M()
{
Console.WriteLine("In class A");
}
}

然后,修改B的实现:

     class B : A
{
public override void M()
{
Console.WriteLine("In class B");
}
}

这样,运行起来就可以得到预期的结果了。
注意,下面这种写法也是错误的,知道问题在哪里吗?

     class B : A, IC
{
new void M()
{
Console.WriteLine("In class B");
}
}

一个关于C#中基类与接口混合继承的疑问总结的更多相关文章

  1. 关于Java中基类构造器的调用问题

    在<Java编程思想>第7章复用类中有这样一段话,值得深思.当子类继承了父类时,就涉及到了基类和导出类(子类)这两个类.从外部来看,导出类就像是一个与基类具有相同接口的新类,或许还会有一些 ...

  2. 基类VS接口

    该篇引用 CLR via C# 中的13.11节. 应该设计基类还是接口,这个问题不能一概而论,下面提供一些指导性原则: 1. IS_A关系(指属于,例如汽车属于交通工具) vs CAN_DO关系(指 ...

  3. C++中基类的析构函数为什么要用virtual虚析构函数

    知识背景 要弄明白这个问题,首先要了解下C++中的动态绑定. 关于动态绑定的讲解,请参阅:  C++中的动态类型与动态绑定.虚函数.多态实现 正题 直接的讲,C++中基类采用virtual虚析构函数是 ...

  4. C++中基类虚析构函数的作用及其原理分析

    虚析构函数的理论前提是 执行完子类的析构函数,那么父类的虚构函数必然会被执行. 那么当用delete释放一个父类指针所实例化的子类对象时,如果没有定义虚析构函数,那么将只会调用父类的析构函数,而不会调 ...

  5. 详解C++中基类与派生类的转换以及虚基类

    很详细!转载链接 C++基类与派生类的转换在公用继承.私有继承和保护继承中,只有公用继承能较好地保留基类的特征,它保留了除构造函数和析构函数以外的基类所有成员,基类的公用或保护成员的访问权限在派生类中 ...

  6. koa 基础(十八)es6中的类、静态方法、继承

    1.app.js /** * es6中的类.静态方法.继承 */ // 定义Person类 class Person { constructor(name, age) { /*类的构造函数,实例化的时 ...

  7. koa 基础(十七)原生 JS 中的类、静态方法、继承

    1.app.js /** * 原生 JS 中的类.静态方法.继承 * es5中的类和静态方法 */ function Person(name, age) { // 构造函数里面的方法和属性 this. ...

  8. C#编程语言与面向对象——抽象基类与接口

    在一个类前加“abstract”关键字,此类就成为抽象类. 对应的,在一个方法前加“abstract”关键字,此方法就成为抽象方法. abstract class Fruit //抽象类 { publ ...

  9. 6、面向对象以及winform的简单运用(抽象基类与接口)

    抽象类与抽象方法 1.书写规范: 在类前面加上abstract关键字,就成为了抽象类:在一个方法前面加上abstract关键字,就成为了抽象方法(抽象方法不能有实现方法,直接在后面加分号) 例: ab ...

随机推荐

  1. sqlserver on linux

    学习SQL Server从在Linux上安装开始 原创 2016-11-18 衡子 衡子hengzi 微软已经发布了SQL Server on Linux,目前支持Redhat和Ubuntu两种发行版 ...

  2. 【MySQL】查询使用临时表

    MySQL查询产生临时表的分析 官网说明的地址:http://dev.mysql.com/doc/refman/5.5/en/internal-temporary-tables.html 参考:htt ...

  3. js控制ul的显示隐藏,对象的有效范围

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. ASP.Net MVC 5 高级编程 第7章 成员资格、授权和安全性

    第7章 成员资格.授权和安全性 7.1 安全性 ASP.NET MVC 提供了许多内置的保护机制(默认利用 HTML 辅助方法和Razor 语法进行 HTML编码以及请求验证等功能特性,以及通过基架构 ...

  5. 简单实现兼容各大浏览器的js复制内容到剪切板

    因为网站文章需要提供几个按钮,单击后实现复制文章内容到剪贴板. 在网上搜索了很多内容,发现都比较乱这里自己整理下,分享给大家 效果图如下: 之前使用的是window.clipboardData.set ...

  6. .net框架

    转载:http://www.cnblogs.com/JimmyZhang/archive/2012/11/27/2790759.html 本书是一本讲解.NET技术的书籍,目标读者群也是在.NET框架 ...

  7. Java应用架构的演化之路

    Java应用架构的演化之路 当我们架设一个系统的时候通常需要考虑到如何与其他系统交互,所以我们首先需要知道各种系统之间是如何交互的,使用何种技术实现. 1. 不同系统不同语言之间的交互 现 在我们常见 ...

  8. [译]MongoDB 3.0发布说明

    原文来自:http://docs.mongodb.org/manual/release-notes/3.0/ 2015年3月3日 MongoDB 3.0现已可供使用.关键新特性包括支持WiredTig ...

  9. nginx+php与apache+php性能对比

    测试工具http_load相同的动态页面测试,相同的硬件资源,相同并发,相同请求数量的前提下,nginx+php比apache+php的性能要 差,而且如果请求的压力大于硬件资源的承受能力,nginx ...

  10. (转)Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询

    1.搭建环境 新建JAVA项目,添加的包有: 有关Hadoop的hadoop-core-0.20.204.0.jar 有关Hbase的hbase-0.90.4.jar.hbase-0.90.4-tes ...