接口对象的实例化在接口回调中的使用

接口是不能实例化的,但是接口可以申明引用。接口的引用可以指向凡是实现了该接口的类的实例。格式如下:

  【接口名】 【对象名】= new 【实现该接口的类】

这是因为面向对象都具有多态,可以向上转型。比如某个类实现了IConnection接口,如类Connection实现了该接口,

则Connection类的实例化对象可以给IConnection接口. 如 IConnection objIConnection = new Connection();

 

申明引用的好处是可是实现统一访问(即统一接口,可以随意指向实现了该接口的类的实例)

例如:http://hi.baidu.com/yimeng3025/blog/item/2cfc7bbe21fb330218d81f4d.html(c#接口详解)

 

ContractedBlock.gif ExpandedBlockStart.gif Code
         假设我们公司有两种程序员:VB程序员,指的是用VB写程序的程 序员,用clsVBProgramer这个类表示;Delphi程序员指的是用Delphi写程序的程序员,用clsDelphiProgramer这个 类来表示。 每个类都有一个WriteCode()方法。定义如下:

class clsVBProgramer()
{
   dot.gif.
   WriteCode()
   {
      
//用VB语言写代码;
   }
   dot.gif.
}

class clsDelphiProgramer()
{
   dot.gif.
   WriteCode()
   {
     
//用Delphi语言写代码;
   }
    dot.gif.
}

现在公司来了一个项目,要求派某个程序员写一个程序。
class clsProject()
{
   dot.gif.
   WritePrograme(clsVBProgramer programer)
//用VB写代码
   {
     programer.WriteCode();
   }
   WritePrograme(clsDelphiProgramer programer)
//重载方法,用Delphi写代码
   {
     programer.WriteCode();
   }
dot.gifdot.gif
}
在主程序中我们可以这样写:
main()
{
    clsProject proj
=new   clsProject;
    
//如果需要用VB写代码
    clsVBProgramer programer1=new clsVBProgramer;
    proj.WritePrograme(programer1);
    
//如果需要用Delphi写代码
    clsDelphiProgramer programer2=new clsDelphiProgramer;
    proj.WritePrograme(programer2);
}

但 是如果这时公司又来了一个C#程序员,我们怎么改这段程序,使它能够实现用C#写程序的功能呢?我们需要增加一个新类 clsCSharpProgramer,同时在此clsProject这个类中要再次重载 WritePrograme(clsCSharpProgramer programer)方法。这下麻烦多了。如果还有C程序员,C
++程序 员,JAVA程序员呢。麻烦大了!

但是如果改用接口,就完全不一样了:
首先声明一个程序员接口:
interface IProgramer()
{
   WriteCode();
}
然后声明两个类,并实现IProgramer接口:
class clsVBProgramer():IProgramer
{
   dot.gif.
   WriteCode()
   {
      
//用VB语言写代码;
   }
   dot.gif.
}

class clsDelphiProgramer():IProgramer
{
   dot.gif.
   WriteCode()
   {
     
//用Delphi语言写代码;
   }
    dot.gif.
}
对clsProject这个类进行一下修改:
class clsProject()
{
   dot.gif.
   WritePrograme(IProgramer programer)
   {
     programer.WriteCode();
//写代码
   }
   dot.gifdot.gif
}

main()
{
    clsProject proj
=new   clsProject;
    IProgramer programer;
    
//如果需要用VB写代码
    programer=new clsVBProgramer;
    proj.WritePrograme(programer);
    
//如果需要用Delphi写代码
    programer=new clsDelphiProgramer;
    proj.WritePrograme(programer);    
}
如果再有C#,C,C
++,JAVA这样的程序员添加进来的话,我们只需把它们相关的类加进来,然后在main()中稍做修改就OK了。扩充性特别好!

另外我们如果把clsProject这个类封成一个组件,那么当我们的用户需要要扩充功能的时候,我们只需要在外部做很小的修改就能实现,可以说根本就用不着改动我们已经封好组件!是不是很方便,很强大!
 

 

接口声明变量:

private IBellListener  bellListener;(注:IBellListener是接口,这句代码只是声明了一个私有的变量,这个私有变量是接口类型的,这时候堆内存中的这个变量未引用栈内存中的实例对象,故并没对其实例化。)

 

接口声明方法:

public IEnumerator<T> GetEnumerator()

    {

        Node current = head;

 

        while (current != null)

        {

            yield return current.Data;

            current = current.Next;

        }

    }

====================================================================================

首先澄清一个问题,就是接口不仅可以声明对象,而且可以把对象实例化!作用见下文。

接口回调:可以把实现某一接口类创建的对象的引用赋给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口中的方法。实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口方法。

我们看下面的例子:
ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

public partial class _Default : System.Web.UI.Page
{
    
protected void Page_Load(object sender, EventArgs e)
    {
        Volume v 
= null;
        Computerable bottom 
= null;
        
//接口变量(bottom)中存放着对对象中实现了该接口的方法的引用
        bottom = new Rec(36);
        Response.Write(
"矩形的面积是:"+bottom.area()+"<br>");
        v 
= new Volume(bottom, 10);
       
//体积类实例的volum方法实际上计算的是矩形的体积,下同
        Response.Write("棱柱的体积是:" + v.volume() + "<br>");
        bottom 
= new Circle(5);
        
        Response.Write(
"圆的面积是:" + bottom.area() + "<br>");
        v.changeBottome(bottom);
        Response.Write(
"圆柱的体积是:"+v.volume());
     
}
}

interface Computerable
{
     
double area();
}

public class Rec:Computerable
{
//矩形
    double a,b;
    
public Rec(double a,double b)
    {
        
this.a = a;
        
this.b = b;
    }

    
public double area() 
    {
        
return (a*b);
    }
}

class Circle :Computerable
{
//圆周
    double r;

    
public Circle(double r)
    {
        
this.r = r;
    }
    
public double area() 
    {
        
return (3.14*r*r);
    } 
}
class Volume 
{
//体积
    Computerable bottom;
    
double h;

   
public Volume(Computerable bottom, double h)
    {
        
this.bottom = bottom;
        
this.h = h;
    }

    
public void changeBottome(Computerable bottom)
    {
        
this.bottom = bottom;
    }

    
public double volume()
    {
        
return (this.bottom.area()*h/3.0);
    }
}
        
结果输出:
            矩形的面积是:18.0
            棱柱的体积是:60.0
            圆的面积是:78.5
            圆柱的体积是:261.6666666666667

            通过上面的例子,我们不难看出,接口对象的实例化实际上是一个接口对象作为一个引用,指向实现了它方法的那个类中的所有方法,这一点非常象C++中的函数指针,
    但是却是有区别的。java中的接口对象实例化实际上是一对多(如果Computerable还有其他方法,bottom仍然可以调用)的,而C++中的函数指针是一对一的。

            但是需要注意的是, 接口对象的实例化必须用实现它的类来实例化,而不能用接口本身实例化。用接口本身实例化它自己的对象在JC#中是不允许的。
 

转载于:https://www.cnblogs.com/291099657/archive/2009/09/30/1576936.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值