惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News and Events Feed by Topic
A
About on SuperTechFans
D
DataBreaches.Net
量子位
云风的 BLOG
云风的 BLOG
T
The Blog of Author Tim Ferriss
U
Unit 42
M
MIT News - Artificial intelligence
小众软件
小众软件
博客园 - Franky
GbyAI
GbyAI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Help Net Security
Help Net Security
Recorded Future
Recorded Future
The Last Watchdog
The Last Watchdog
S
Secure Thoughts
S
Security @ Cisco Blogs
MongoDB | Blog
MongoDB | Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
IT之家
IT之家
L
LINUX DO - 热门话题
H
Hacker News: Front Page
V
Vulnerabilities – Threatpost
Security Latest
Security Latest
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - 叶小钗
J
Java Code Geeks
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Hugging Face - Blog
Hugging Face - Blog
PCI Perspectives
PCI Perspectives
Cyberwarzone
Cyberwarzone
S
Schneier on Security
Scott Helme
Scott Helme
Microsoft Security Blog
Microsoft Security Blog
Attack and Defense Labs
Attack and Defense Labs
T
The Exploit Database - CXSecurity.com
C
Cisco Blogs
Y
Y Combinator Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
Tenable Blog
Google DeepMind News
Google DeepMind News
T
Threat Research - Cisco Blogs
H
Hackread – Cybersecurity News, Data Breaches, AI and More
www.infosecurity-magazine.com
www.infosecurity-magazine.com
V
V2EX
美团技术团队
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
大猫的无限游戏
大猫的无限游戏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Know Your Adversary
Know Your Adversary

博客园 - hgtj

谈谈产品和项目 重新开始写博客 组件 访问被拒绝 --“/”应用程序中的服务器错误。IIS重启不行,系统注销也不行 (转).Net 揭密--JIT怎样运行你的代码 第一部分 (普通调用) MS-SQLSERVER数据库SUSPECT状态如何解决 Com Interop入门 可按任意字段排序的分页存储过程(转) 拨开SOA的面纱(一篇对SOA概念讲解的很透彻的文章) 基于角色管理的系统访问控制 MySQL查询优化系列讲座之查询优化器 SQL语句优化技术分析 对ORM的疑问 MonoRail - 生命周期及controller/action/view详解 (转) 了解AOP(转) 思归的“动态控件的状态问题”的分析 Asp.Net 背后原理 关于类型转换方面的备忘 java设计模式之State(转) javascript 实现类似C#中字符串的Trim()方法
接口的终结解释 (转)
hgtj · 2006-03-21 · via 博客园 - hgtj

接口的终结解释

转载地址: http://www.cnblogs.com/wujm/archive/2005/05/16/156473.html

接口
简单的说接口就是一个契约或者规范.比如遥控器,国家出台了一个国家遥控器规范,明文要求所有的遥控器厂家都要遵循这个规范,如果不遵循规范就不给3C认证标志,就不允许上市出卖..为什么要这个规范呢?大家在时间生活中会经常碰到,甲厂的遥控器不能遥控乙厂的电视,电视遥控器不能遥控其它电器如空调,冰箱.!原因是什么呢?是各个遥控器都没有遵循一个规范,电波有长有短,电压有高有低,导致各自为政,4分5列!  
    可以想像出国家遥控器标准只是是规定遥控器的一些重要技术指标,比如要发射波应该多长,电压应该多高,...,但它绝对不会规范出遥控器的材质,形状,重量和颜色,也是说规范把所有同遥控无关的东西都抛弃了!每个遥控器厂家只要遵循了规范,那么对遥控器可以有任意的诠释.比如A厂可以用铁做,牢固无比,B厂可以用纸,可以任意折叠,anyway,不管用什么做,做出什么样子,只要遵循规范的遥控器就可以遥控所有的电器(当然电器厂家也要遵循一定的规范),甚至可以遥控导弹发射!利害吧,这就是接口的威力.  
    再详细点,接口就是一个规范,他和具体的实现无关!接口是规范(虚的),他只是一张纸,也是说在实际的使用中接口只有依托一个实现了它的类的实例,才会有意义,如上面的各个厂家做的遥控器产品.每个实现接口的类(厂家)必需实现接口中所有的功能.  一旦一个类实现了一个接口,就可说一个类和接口捆绑了(这个很重要,做题目的时候会用到)
    来个例子
    interface  遥控器规范    //国家定义的遥控器规范  ,每个遥控器厂家必需实现(诠释)它
    {
          int  波长();
          int  电压();
    }
    class    甲厂铁遥控器  :  遥控器规范    //甲厂的遥控器实现(诠释)了这个规范,它和遥控器规范捆绑了!好,它可以在市场上出售了
    {
          public  int  波长();                        //规范上定义的指标  
          public  int  电压();                        //规范上定义的指标  
          public  int  形状()  {  正方形};          //甲厂自己对该产品的诠释    
          public  int  材质()  (  铁  };                  //甲厂自己对该产品的诠释
    }
    class  乙厂纸遥控器  :  遥控器规范    ////甲厂的遥控器实现(诠释)了这个规范,它和遥控器规范捆绑了!好,它可以在市场上出售了
    {
          public  int  波长();                      ////规范上定义的指标  
          public  int  电压();                    //规范上定义的指标        
          public  int  形状()(  圆形);          //甲厂自己对该产品的诠释,是圆形
          public  int  材质()(  纸);              //甲厂自己对该产品的诠释,用纸做,好酷!      
    }
    class  电器
    {procedure  接收遥控(遥控器规范  )    //电器上,接收遥控指令
        {.....
              接收(遥控器规范.波长)  ;              
              接收(遥控器规范.电压);
              .....}      }    
    static  main()
    {
        甲厂铁遥控器    ControlA    ;    //申明控制器对象
        乙厂纸遥控器    ControlB    ;
        ControlA    =  new  甲厂铁遥控器();  //实例化控制器对象,这个时候系统在托管堆中为该对象分配了空间
        ControlB    =  new  乙厂纸遥控器()  ;
        遥控器规范    ControlInterfaceA  =  (遥控器规范)遥控器1  ;    //把对象实例转换成一个规范,为什么呢?因为"我家的电器".只能识别遥控器规范,它识别不到具体的遥控器
        遥控器规范    ControlInterfaceB  =  (遥控器规范)遥控器2;    //同上
        电器    我家的电器  =  new  电器();
        我家的电器.接收遥控(ControlInterfaceA)    //我用甲厂遥控器遥控我家的电器.  注意:  这里的ControlInterfaceA是不能单独存在的,它必要依赖实现了"遥控器规范"的类的实例"ControlA".道理很简单,接口是一个指针,不会被分配空间,你就无法使用,只有和一个具体类的实例联系了,才有了可以活跃空间.
        我家的电器.接收遥控(ControlInterfaceB)    //我用乙厂遥控器遥控我家的电器
        
        ...
        //下面是我的的想像,我可以用遥控器来控制导弹发射!
        我的导弹.接收遥控(ControlInterfaceA);
        我的导弹.接收遥控(ControlInterfaceB);        
        ...
    }
--------------------------------------------------------------------
接口的执行
好了,有了接口的概念,再来谈c#程序在运行中是如何使用接口的,如何访问接口函数.具体流程如下
    a.当调用一个接口的函数时,系统会去检查这个接口对应实例是什么?
    b.找到这个实例后,再去找这个实例对应的实例类是什么(什么是实例类,参看读书笔记二)
    c.根据这个实例类去检查该实例类是否和接口发生了捆绑(看是否实现了该接口,冒号后面就是)
    d.好!如果实例类实现了该接口(发生了捆绑)  ,它就在这个实例类中找函数的定义.然后执行该函数.执行结束.
    e.如果没找到,他就继续往父类找,直到找到第一个和接口捆绑的父类为止
    f.找到后,它再检查该函数是否是虚拟函数,
    g.如果不是,他马上就执行它  .
    h  如果是,麻烦了,系统又要从头来过,去检查该实例类的函数是否重载了该函数,...具体过程见(c#读书笔记2).
    例子:
    
using System;

namespace ConsoleApplication1
{
 /// <summary>
 /// Class1 的摘要说明。
 /// </summary>
 public interface  I
 {
  void  Func();
 }
        
 class  A :I 
 {
  public  virtual  void  Func() 
  { 
   Console.WriteLine("FuncA");
  }
 }
       
 class  B  :  A  ,  I    //注意这里的意思?
 {
  public  void  Func()  {  Console.WriteLine("FuncB");}
 }       
       
 class  C  :    A 
 {
  public  override  void  Func()  {  Console.WriteLine("FuncC");}
 }   

 class Class1
 {
  /// <summary>
  /// 应用程序的主入口点。
  /// </summary>
  [STAThread]
  static void Main()
  {
   I  a  =  new  A()  ;    //申明了接口a,并马上和一个类的实例发生关系了
   I  b  =  new  B()  ;    //申明了接口b,并马上和一个类的实例发生关系了
   I  c  =  new  C()  ;    //申明了接口c,并马上和一个类的实例发生关系了
   a.Func()  ;              //检查a的实例A,  发现A和接口I捆绑了,所以执行A的函数Func  ,结果:  FuncA
   b.Func()  ;              //检查b的实例B,  发现B和接口I捆绑了,所以执行B的函数Func  ,结果:  FuncB
   c.Func()  ;              //家常c的实例C,发现其没有和接口I捆绑,系统继续找它的父类.  发现A和I捆绑了,他就去找函数A,发现A是虚拟函数,系统又从头来找类的实例C,发现C重载(override)了Func,好了,马上执行该函数.  结果是FuncC;
   Console.ReadLine();
  } 
 }
}