并非只能通过继承使用多态性,还能通过接口使用它。
和抽象类不同,接口不包含任何实现(方法)。
然后和抽象类相似,接口也定义了一系列成员,调用者可以依赖这些成员来支持一个特定的功能。
 
实现接口的类会使用与被实现的接口相同的签名来定义方法。
 
通过基类来共享成员签名和实现,但通过接口只是共享成员签名,不共享实现。
 
接口的一个关键特征就是它既不包含实现,也不包含数据。
字段不能出现在一个接口中。
但是可以使用属性,由于属性不会包含任何实现作为接口声明的一部分,所以它不会引用一个支持字段。
C#不允许为接口成员使用访问修饰符。所有成员都自动定义为pulbic成员。
 
一旦某个类声明自己要实现一个接口,则该接口的所有成员都必须实现。
接口的一个重要特征在于,它们永远不能被实例化,不能使用new来创建一个接口。
也正是这个原因,接口不能有构造器或终结器。接口实例只适用于实现它们的类型。
除此之外,接口不能包含static成员。接口的一个重要目的就是实现多态性
 
显式接口实现 ,隐式接口实现  
在重写的方法和属性前是否添加接口名。
1、显式成员实现
在实现的方法和属性前加上接口名。
由于显式接口实现直接与接口关联,因此没有必要使用virtual、override或者public来修饰它们。
 
2、隐式成员实现
不在实现的方法和属性前加上接口名。
直接使用方法名和属性名
隐式成员实现必须是public的,除此之外,virtual是可选的,具体取决于派生类是否可以重写实现。
如果去掉virtual,该成员就如同是sealed成员。且override是不允许的。
由于成员的接口声明不包含实现,所以override没有意义。
 
3、显式接口实现与隐式接口实现的比较。
显式接口实现是将“机制方面的考虑”与“模型方面的考虑”分隔开的一种技术。
要求调用者先将对象转换为接口,然后才能认为对象是“可比较”的,可显式地区分你想在什么时候和模型 进行沟通,
以及想在什么时候和实现机制打交道。
以下一些基本的设计原则,可以利用它们来帮助自己选择显式还是隐式实现。
 成员是不是核心的类功能
是:隐式
否:显式
接口成员名作为类成员是否恰当
是:隐式
否:显式
是否已经有一个同名的类成员
是:隐式
否:显式

     class Program
{
static void Main(string[] args)
{ IListTable i;
Contact c = new Contact();
c.Name = "name1";
Console.WriteLine(c.ColnumName); Appointment a = new Appointment();
a.Name = "name2";
Console.WriteLine(((IListTable)a).ColnumName); Console.ReadLine(); }
} interface IListTable
{
string ColnumName
{ get; }
}
public class Contact : IListTable
{
public string Name
{
get
{
return FirtstName;
}
set
{
FirtstName = value + " from Contact";
}
}
private string FirtstName;
//隐式实现
public string ColnumName
{
get { return FirtstName + " ColnumName"; }
set { FirtstName = value; }
} }
public class Appointment : IListTable
{
public string Name
{
get
{
return FirtstName;
}
set
{
FirtstName = value + " from Appointment";
}
}
private string FirtstName; //显式实现
string IListTable.ColnumName
{
get { return FirtstName + " ColnumName"; }
//set { FirtstName = value; }//错误
} }
 
 
4、实现类与其接口之间的转型
在实现类的实例中总是包含了接口中的全部成员,所以对象总是能成功转型为接口类型。
从接口类型转为它的实现类,需要执行一次显式的转型。
 
5、接口继承
一个接口可以从另一个接口派生,派生的接口将继承“基接口”的所有成员。
 
在用于显式接口成员实现的一个完全限定的接口成员名称中,必须引用最初声明它的那个接口的名称。
 

      class Program
{
static void Main(string[] args)
{ }
} public interface IReadAbleSettingsProvider
{
string GetSetting(string name, string defaultValue);
}
public interface ISettingsProvider : IReadAbleSettingsProvider
{
void SetSetting(string name, string value);
}
class FileSettingsProvider : ISettingsProvider
{
public void SetSetting(string name, string value)
{
//
}
string IReadAbleSettingsProvider.GetSetting(string name, string defaultValue)
{
//
return " ";
}
}
即使类实现了从基接口派生的一个接口,类仍然可以公开声明两个接口的实现(两个接口都继承实现,放在限定符后面:)

     class FileSettingsProvider : ISettingsProvider, IReadAbleSettingsProvider
{
public void SetSetting(string name, string value)
{
//
}
string IReadAbleSettingsProvider.GetSetting(string name, string defaultValue)
{
//
return " ";
}
}
 
7、多接口继承
就像类能实现多个接口那样,接口也可以从多个接口继承,而且语法与类的继承和实现的语法是一致的。
 
8、接口上的扩展方法
可以在别的类中为接口添加一个成员方法。(扩展方法必须在静态类中定义,且扩展方法需要static修饰)
 
C#不仅允许为一个特定的对象实例添加扩展方法,还通话为那些对象的一个集合添加扩展方法。对扩展方法的支持是实现
LINQ的基础 。
IEnumerable是所有集合都要实现的基础接口。
通过为IEnumberable定义扩展方法,为所有集合都添加了LINQ支持。
这显著地改变了对象集合的编程方式。

     class Program
{
static void Main(string[] args)
{ Contact[] items = new Contact[] { new Contact(), new Contact() };
for (int i = ; i < items.Length; i++)
{
items[i].ColnumName = "name" + i;
}
items.ListColumn(); Console.ReadLine(); }
} interface IListTable
{
string ColnumName
{ get; }
}
public class Contact : IListTable
{
public string Name
{
get
{
return FirtstName;
}
set
{
FirtstName = value + " from Contact";
}
}
private string FirtstName;
//隐式实现
public string ColnumName
{
get { return FirtstName + " ColnumName"; }
set { FirtstName = value; }
} } static class Listable
{
public static void ListColumn(this IListTable[] items)
{
string headers = "";
for (int i = ; i < items.Length; i++)
{
headers += items[i].ColnumName + ",";
}
Console.WriteLine(headers);
}
}
输出:
name0 ColnumName,name1 ColnumName,
 
 
8、通过接口实现多重继承
虽然类只能从一个基类派生,但可以实现任意数量的接口,这有效解决了C#类不支持多重继承的问题。
为此,我们要像上一章讲述的那样使用聚合,但可以稍微改变一下结构,在其中添加一个接口。
需要写代码:

     public class PdaItem
{
public PdaItem()
{
}
public PdaItem(DateTime pLastUpdated)
{ LastUpdated = pLastUpdated;
}
public DateTime LastUpdated { set; get; }
}
interface IPerson
{
string FirstName { set; get; }
string LastName { set; get; }
}
public class Person : IPerson
{
public string Address { set; get; }
public string Phone { set; get; } public string FirstName { set; get; }
public string LastName { set; get; }
}
//使用聚合(实现继承Person 和 PdaItem 两个类,并将方法和属性放到接口当中
public class Contact : PdaItem, IPerson
{
private Person _Person;
public Person person
{
set
{
_Person = value;
}
get
{
return _Person;
}
}
public string FirstName
{
get
{
return _Person.FirstName;
}
set
{
_Person.FirstName = value;
}
}
public string LastName
{
get
{
return _Person.LastName;
}
set
{
_Person.LastName = value;
}
} }
    //IPerson 确保Person的成员和复制到Contact的成员具有一致的签名,然而,这个实现仍然没有作到"多重继承"真正同义
    //,因为添加到Person的新成员不会同时添加到Contact上(以上的是接口的实现没有带过来,也不能进行重写,只能利用继承这个接口,实现这个接口,重写那两个属性)。
    //如果被实现的成员是方法(不是属性),那么有一个办法可以对此进行改进。具体地说,就是为从第二个基类"派生"的附加功能定义接口扩展方法。
    //例如,IPerson上的一个扩展方法可以提供一个名为VerifyCredentials()的方法。这样一来,实现了IPerson的所有类(即使IPerson接口没有成员,只用扩展方法)
    //都会有VerifyCredentials()的一个默认实现。这之所以可行,完全是多态性和重写的功能。之所以支持重写,是因为一个方法的任何实例实现都要优先
    //具有相同静态签名的一个扩展方法。
9、版本控制
需要对程序增加功能时,不应该修改原来的接口,而是再定义一个接口,然后继承原来的接口,新接口上添加功能定义,
再使需要增加功能的类实现该接口。
 
10、接口与类的比较 
接口引入 了另一个类别的数据类型(它们是少数不对终极基类System.Object进行扩展的类型之一,此外还有指针类型和类型参数类型)
 
然后,和类不同的是,接口永远不能实例化。要访问一个接口p痊,只能通过对实现了接口的一个对象的引用来进行。
不能为接口使用new运算。所以,接口不能包含任何构造器或终结器,除此之外,静态成员在接口上是不允许的。
 
接口近似于抽象类,两者具有一些共同的特点。
 
 
 
 
 

七、C# 接口的更多相关文章

  1. Java基础知识笔记(七:接口、变量作用域和参数传递)

    一.接口 Java语言不允许一个子类拥有多个直接父类,即任何子类只能有一个直接父类.但允许一个类实现多个接口,即在定义类的接口名称列表中可以包含1个或多个接口名称,从而实现多重继承的特性.接口的定义格 ...

  2. Verilog学习笔记简单功能实现(七)...............接口设计(并行输入串行输出)

    利用状态机实现比较复杂的接口设计: 这是一个将并行数据转换为串行输出的变换器,利用双向总线输出.这是由EEPROM读写器的缩减得到的,首先对I2C总线特征介绍: I2C总线(inter integra ...

  3. 深入struts2.0(七)--ActionInvocation接口以及3DefaultActionInvocation类

    1.1.1       ActionInvocation类 ActionInvocation定义为一个接口.主要作用是表现action的运行状态.它拥有拦截器和action的实例.通过重复的运行inv ...

  4. 前端js调用七牛制作评价页面案例

    一.需求 公司所有的上传页面都用七牛,前端不免要直接调用七牛的代码进行上传,以下是一个实现七牛上传的案例,制作一个常见的商品评价页面,页面需求很常见当上传到第五章图片的时候,上传按钮消失,上传需要显示 ...

  5. Effective Java 读书笔记之三 类和接口

    一.使类和成员的可访问性最小化 1.尽可能地使每个类或者成员不被外界访问. 2.实例域决不能是共有的.包含公有可变域的类不是线程安全的. 3.除了公有静态final域的特殊情形之外,公有类都不应该包含 ...

  6. 【UEditor】远程上传图片到【七牛云存储】

    杂谈:最近在玩一个第三方的微信开发平台,里面的图片都是上传到[七牛云存储]的,用了一下非常的好用,支持各种语言,SDK齐全.支持全分布式系统架构以及存储技术和数据加速,于是决定将网站的图片都存储到七牛 ...

  7. 接口(三)——JAVA的多重继承

    一.接口的作用 ①.为了能够向上转型为多个基类型 ②.防止客户端程序员创建该类的对象——同抽象类 二.通过继承扩展接口 interface Monster{ void menace(); } inte ...

  8. 七牛php-sdk使用-文件上传

    使用七牛进行文件上传可以有多种方式: 直接form表单上传,需要自己按照文档做配置 使用七牛jssdk,部署较简单,大文件分片上传 php-sdk后台上传 首先,所有的上传方法以及所有的跟七牛接口相关 ...

  9. golang面向对象和interface接口

    一. golang面向对象介绍 1.golang也支持面向对象编程,但是和传统的面向对象编程有区别,并不是纯粹的面向对象语言.2.golang没有类(class),golang语言的结合体(struc ...

  10. Java开发知识之Java的继承多态跟接口*

    Java开发知识之Java的继承多态跟接口 一丶继承 1.继承的写法 在Java中继承的 关键字是 extends 代表一个类继承另一个类. 继承的含义以及作用: 继承就是基于某个父类的扩展.制定出来 ...

随机推荐

  1. The Same Game(模拟)

    http://poj.org/problem?id=1027 题意:给一个10*15的地图,里面填充R,G,B三种颜色,每次找到当前地图的同色最大区域M,并将其删除,删除M后,上面的小球自然下落,当有 ...

  2. HDU 5452 Minimum Cut

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=5452题目大意: 给你一个图G,图中包含一颗生成树.要求只能删除生成树内的一条边,使得图不联通.问最小的删除 ...

  3. 【模拟】Codeforces 699A Launch of Collider

    题目链接: http://codeforces.com/problemset/problem/699/A 题目大意: 给N个点,向左或向右运动,速度均为1,问最早什么时候有两个点相撞.无解输出-1 题 ...

  4. oracle 表查询(1)

    oracle 表基本查询 介绍在我们讲解的过程中我们利用scott 用户存在的几张表(emp,dept)为大家演示如何使用select语句,select 语句在软件编程中非常有用,希望大家好好的掌握. ...

  5. Delphi NativeXml用法攻略

    NativeXml用法攻略 NativeXml可以在官网上下载,下载后将文件夹放在指定地方,打开DELPHI在其环境变量中引用NativeXml路径,然后在程序中引用NativeXml单元,我们就可以 ...

  6. log4cxx在vs2013的静态编译

    网络上找了一圈,结果都是通过修改代码来编译,做为强迫症患者接受不了这种修改代码却无法预知代码带来影响的方式,而且没有静态编译的方法,为了方便其他人后续不在走弯路,提供自己的编译方法. 虽然最终的目的是 ...

  7. 6种GET和POST请求发送方法

    我试过了畅言和多说两种社会化评论框,后来还是抛弃了畅言,不安全. 无论是畅言还是多说,我都需要从远程抓取文章的评论数,然后存入本地数据库.对于多说,请求的格式如下: // 获取评论次数,参数是文章ID ...

  8. OpenReports操作指南

    最近要玩OpenReports,但在网上找了一圈,能用的资料少得可怜,所以把最近使用下来,积累的一些技巧记录下来(有部分整合了网上的资源). 备注:以下操作说明基于已做汉化的项目(汉化方案请参考:ht ...

  9. js~一个列表中包含上移下移删除等功能

    最近做了一个项目,包括了一个列表页,为了用户体验,操作均使用JS实现,其中包括在列表中实现上移,下移,删除等功能,前台JS,后端数据修改使用AJAX,本文主要说一下前台JS这块 先看一下页面的截图

  10. 九度OnlineJudge之1001:A+B for Matrices

    题目描述: This time, you are supposed to find A+B where A and B are two matrices, and then count the num ...