C#中显/隐式实现接口及其访问方法
原贴地址: http://www.cnblogs.com/dudu837/archive/2009/12/07/1618663.html
在实现接口的时候,VS提供了两个菜单,一个是"实现接口",一个是"显式实现接口",它们到底有何不一样呢
我们来比较一下看看
1.首先假设我们有一个接口
public interface ICustomer
{
void SomeMethod();//接口的所有成员都暗自成为abstract,我们不能为它提供缺省实现,无论这份实现是 多么平淡无奇;接口的成员也都暗自成为public,我们不能以关键字abstract或 public来修改(修饰)其中某个成员。
}
2.如果是"实现接口",那么代码大致如下
public class Customer:ICustomer
{
#region ICustomer 成员
public void SomeMethod()
{
throw new NotImplementedException();
}
#endregion
}
3.如果是"显式实现接口",那么代码大致如下
public class Customer:ICustomer
{
#region ICustomer 成员
void ICustomer.SomeMethod()//显示接口成员的访问级别暗中是public,不允许程序员再加任何修饰符
{
throw new NotImplementedException();
}
#endregion
}
大家看到差别了吧?显式实现的方式,那些方法都会加上一个前缀的。但是,这到底意味着什么呢?
如果是实现接口
public class DAL {
/// <summary>
/// 如果我们是直接实现接口的话,那么既可以用接口调用方法,也可以用具体类调用方法
/// </summary>
public void GetCustomer() {
Customer customer = new Customer();
customer.SomeMethod();
}
public void GetCustomer2() {
ICustomer customer = new Customer();
customer.SomeMethod();
}
}
如果是显式实现接口
public class DAL {
/// <summary>
/// 如果我们是显式实现接口的话,那么要访问里面的方法就只能是通过接口来调用,而不能通过具体类来做
/// </summary>
public void GetCustomer() {
ICustomer customer = new Customer();
customer.SomeMethod();
}
}
此外,我们还可以在继承接口的类中同时提供实现接口和显式实现接口两种方式,这样就完成了对一个接口成员提供多份实现实体,访问时可以用类的实例和接口的引用来分别调用这两种实现实体。
现在大部分的系统为了保证扩展性,都广泛地使用接口。显式实现接口,可以隐藏具体类的复杂性。
1.隐式实现的接口
- interface IControl
- {
- void Paint();
- }
- public class EditBox : IControl
- {
- public void Paint()
- {
- Console.WriteLine("Pain method is called!");
- }
- }
- class Test
- {
- static void Main()
- {
- EditBox editbox = new EditBox();
- editbox.Paint();
- ((IControl)editbox).Paint();
- Console.ReadKey();
- }
- }
结果:
Pain method is called!
Pain method is called!说明:从实例中我们可以看到用隐式实现的接口既可以通过类来访问,也可以通过接口来访问!
2.显式实现的接口
- interface IControl
- {
- void Paint();
- }
- public class EditBox : IControl
- {
- void IControl.Paint()
- {
- Console.WriteLine("IControl.Pain method is called!");
- }
- }
- class Test
- {
- static void Main()
- {
- EditBox editbox = new EditBox();
- //editbox.Paint();//通过类访问会出错
- ((IControl)editbox).Paint();
- Console.ReadKey();
- }
- }
结果:
IControl.Pain method is called!说明:从实例中我们可以看到用显式实现的接口只能通过接口来访问,如果试图通过类来访问会出错:““ConsoleApplication1.EditBox”并不包含“Paint”的定义。”
3.同时用显/隐式实现接口会怎么样?
- interface IControl
- {
- void Paint();
- }
- public class EditBox : IControl
- {
- void IControl.Paint()
- {
- Console.WriteLine("IControl.Pain method is called!");
- }
- public void Paint()
- {
- Console.WriteLine("Pain method is called!");
- }
- }
- class Test
- {
- static void Main()
- {
- EditBox editbox = new EditBox();
- editbox.Paint();
- ((IControl)editbox).Paint();
- Console.ReadKey();
- }
- }
结果:
Pain method is called!
IControl.Pain method is called!说明:当同时用显/隐式实现接口时,显式才是真正的接口实现方法!
4.结论
在
多数情况下,我们都是用隐式来实现接口,此时既可以通过类来访问,又可以通过接口来访问,而通过显式实现的接口则只能通过接口来访问,总结一下就是:当显
式实现方式存在时,隐式实现方式就失效了。但这不能表示显式实现方式就不好,当一个类实现的多个接口中具有相同的方法时,用显式方式来专门实现某个接口的
方法时就显得非常有用!
C#中显/隐式实现接口及其访问方法的更多相关文章
- 编写高质量代码改善C#程序的157个建议——建议47:即使提供了显式释放方法,也应该在终结器中提供隐式清理
建议47:即使提供了显式释放方法,也应该在终结器中提供隐式清理 在标准的Dispose模式中,我们注意到一个以~开头的方法,如下: /// <summary> /// 必须,防止程序员忘记 ...
- C#实现接口的两种方式:显示实现和隐式实现接口
本示例声明一个接口IDimensions 和一个类 Box,显式实现了接口成员 GetLength 和 GetWidth. 通过接口实例 dimensions 访问这些成员. interface ID ...
- Scala 中的隐式转换和隐式参数
隐式定义是指编译器为了修正类型错误而允许插入到程序中的定义. 举例: 正常情况下"120"/12显然会报错,因为 String 类并没有实现 / 这个方法,我们无法去决定 Stri ...
- JSP——JavaServer Page中的隐式对象(implicit object)、指令(directive)、脚本元素(scripting element)、动作(action)、EL表达式
目录 1.JSP概述 2.注释(comment) 2.1.JSP注释 2.2.HTML注释 3.隐式对象(implicit object) 3.1.隐式对象清单 3.2.request对象 3.3.o ...
- C#中的隐式转换
你是否考虑过这个问题:为什么不同类型之间的变量可以赋值,而不需要强制转换类型?如: int i = 1; long l = i; object obj = 1; Exception exception ...
- Scala 深入浅出实战经典 第62讲:Scala中上下文界定内幕中的隐式参数实战详解
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...
- javascript中的隐式类型转化
javascript中的隐式类型转化 #隐式转换 ## "+" 字符串和数字 如果某个操作数是字符串或者能够通过以下步骤转换为字符串的话,+将进行拼接操作. 如果其中一个操作数是对 ...
- 深入探究js中的隐式变量声明
前两天遇到的问题,经过很多网友的深刻讨论,终于有一个相对可以解释的通的逻辑了,然后我仔细研究了一下相关的点,顺带研究了一下js中的隐式变量. 以下文章中提到的隐式变量都是指没有用var,let,con ...
- JavaScript中关于隐式转换的一些总结
JavaScript运算符中的隐式转换规律:一.递增递减运算符(前置.后置)1.如果包含的是有效数字字符串或者是有效浮点数字符串,则会将字符串转换(Number())为数值,再进行加减操作,返回值的类 ...
随机推荐
- UI进阶 SQLite错误码
#define SQLITE_OK 0 /* 成功 | Successful result */ /* 错误码开始 */ #define SQLITE_ERROR 1 /* SQL错误 或 丢失数据库 ...
- MES系统的有用存储过程
USE [ChiefmesNEW]GO/****** Object: StoredProcedure [dbo].[st_WMS_ImportStockInBill] Script Date: 10/ ...
- Struts 2.x异常:Unable to load configuration..../WEB-INF/lib/struts2-convention-plugin-2.1.6.jar!/struts-plugin.xml:30:119
Struts 2.x异常:Unable to load configuration..../WEB-INF/lib/struts2-convention-plugin-2.1.6.jar!/strut ...
- Android APK方式换肤实现原理
现在很多APP都有换肤的功能,例如微博,QQ等应用.这些应用的换肤原理是什么? 在用微博的时候,不难发现,当你要换肤时,先下载并安装一个皮肤apk,然后选择这个皮肤,就可以了. 这种方式就是把皮肤打包 ...
- C++ 排序函数 sort(),qsort()的使用方法
想起来自己天天排序排序,冒泡啊,二分查找啊,结果在STL中就自带了排序函数sort,qsort,总算把自己解脱了~ 所以自己总结了一下,首先看sort函数见下表: 函数名 功能描写叙述 sort 对给 ...
- mybatis0212 mybatis逆向工程 (MyBatis Generator)
1mybatis逆向工程 (MyBatis Generator) .1什么是mybatis的逆向工程 mybatis官方为了提高开发效率,提高自动对单表生成sql,包括生成 :mapper.xml.m ...
- 从cin读入一组词并把它们存入一个vector对象,然后设法把所有词都改写为大写字母。
#include<iostream> #include<vector> #include<string> using namespace std; int main ...
- Naive Bayes Algorithm
朴素贝叶斯的核心基础理论就是贝叶斯理论和条件独立性假设,在文本数据分析中应用比较成功.朴素贝叶斯分类器实现起来非常简单,虽然其性能经常会被支持向量机等技术超越,但有时也能发挥出惊人的效果.所以,在将朴 ...
- Centos 安装KScope1.6.2
准备工作:安装ctags graphviz,和cscope (可以用yum install来安装) 1.首先下载kscope,最好下载16.x的版本,这个最好的 下载kscope-1.6.2.tar ...
- BootStrap2学习日记4---常用标签与样式
<small>:常常和h1标签一起搭配使用 如<h1>标题<small>小标题</small></h1> <abbr>:abbr ...