【转】隐式接口和显式接口

隐式接口和显式接口

C#中对于接口的实现方式有隐式接口和显式接口两种,本文讨论了隐式接口和显式接口的一些区别,并延伸了语言设计层面背后的一些个人体会。

隐式实现和显示实现的例子

隐式地实现接口成员

创建一个接口,Chinese,包含一个成员 Speak;我们创建一个类Speaker,实现接口Chinese

 

复制代码
// 隐藏式实现例子
public   interface  Chinese
{
    
string Speak();
}


public   class  Speaker : Chinese
{
    
public string Speak()
    
{
        
return "中文";
    }


}


复制代码

这个就是隐式实现

显式地实现接口成员 -- 创建一个仅通过该接口调用并且特定于该接口的类成员。这是使用接口名称和一个句点命名该类成员来实现的。

创建一个接口,English,包含一个成员 Speak;让我们的类Speaker来实现接口English

 

复制代码
// 显式实现例子
public   interface  English
{
    
string  Speak();
}

public   class  Speaker : English
{
     
string  English.Speak()
    {
        
return   " English " ;
    }
}
复制代码

 

  隐式实现和显示实现的区别

1.      语法层面的区别

l          隐式方式Speaker的成员(Speak)实现有而且必须有自己的访问修饰符(public),显示实现方式Speaker的成员(Speak)不能有任何的访问修饰符。

l          显示实现方式Speaker使用接口名称和一个句点命名该类成员(Speak)来实现的:English.Speak()

2.      Client的使用者层面

隐式实现的客户端调用,注意类的声明,可以用接口声明,也可以用实现类 Speaker声明。调用者都可以得到调用实例化对象的行为Speak;

 

复制代码
class  Program
{
    
static   void  Main( string [] args)
    {
        Chinese c 
=   new  Speaker();
        c.Speak();

        Speaker s 
=   new  Speaker();
        s.Speak();
    }
}
复制代码

  显式实现的客户端调用,注意类的声明,只可以用接口声明,调用者才可以可以得到调用实例化对象的行为Speak;   

 

Code

 

隐示实现对象声明为接口和类都可以访问到其行为, 显示实现只有声明为接口可以访问。

选择隐式实现还是显示实现

隐式和显式接口实现的关键区别显然并不在于方法声明,而是在于从类外部的可访问性。以下是一些基本的设计原则,可以利用它们来帮助自己选择显式还是隐式实现。

1. 业务语义的考虑?

  考虑接口Chinese和English对于成员的Speak的业务需求,Speaker要实现这两个接口,如果采用隐式实现,语法没有问题,业务满足了吗?

例如:

 


//服务端:
public class Speaker : English, Chinese
{
    public 
 
string  Speak()
    {
        
return   " English " ;
    }
}

// 调用端:
class  Program
{
    
static   void  Main( string [] args)
    {
        Chinese c 
=   new  Speaker();
        c.Speak();
    }
}

呵呵,这完全可以编译通过,但是放在实际的业务场景去考虑,这不是很幽默吗?

这个时候就考虑使用一个显式的实现


 //服务端:
 public class Speaker:English,Chinese

    {
        
string English.Speak()
        {
            
return "English";
        }

        
string Chinese.Speak()
        {
            
return "中文";
        }
}

//调用端:
   class Program
    {
       
string English.Speak()
        {
            
return "English";
        }

        
string Chinese.Speak()
        {
            
return "中文";
        }
}

 

2. 实现类是否准备让调用者独立使用?

虽然显示接口实现提供了更好的封装性,对调用者使用可以强制其进行接口声明,但是如果你准备让用户可以单独使用你这个类的功能,请提供隐式实现。

C#中的接口VS Java中的接口

Java中并没有在语言层面提供隐式和显式接口的实现,那么对于我们例子的中场景如何解决?当然有办法,只是没有C#优雅,还是Java故意在语言层面不提供这样的解决方案,难道认为他破坏了类的单一职责原则?我也在想这个问题,是不是一个Speaker只实现Chinese或者English之一那才是比较好的设计?

C#中接口总结

口描述的是可属于任何结构的一组相关功能。接口可由方法、属性、事件、索引器或这四种成员类型的任意组合构成。接口不能包含字段。接口成员一定是公共的,而且是默认的,不要画蛇添足。

当类或结构继承接口时,意味着该类或结构为该接口定义的所有成员提供实现。接口本身不提供类或结构能够以继承基类功能的方式继承的任何功能。但是,如果基类实现接口,派生类将继承该实现。

如果一个类机继承类并实现接口,一定要吧类写在符号:后面的第一个位置。

推荐阅读:

http://msdn.microsoft.com/zh-cn/library/4taxa8t2.aspx

http://zhenyulu.cnblogs.com/archive/2006/04/18/377705.html


原文出处:http://www.cnblogs.com/Roping/archive/2009/11/08/1598462.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值