不明白接口到底有什么用途。
只讨论接口的方法,假设c#同样支持类的多继承(当然这个假设是错误的),目的是排除接口的多继承特点。
首先继承类必须实现接口的方法,在编译的时候必须去实现结构。那么可以在类中直接声明一个接口。
我实在搞不明白其中的机制。

解决方案 »

  1.   

    你先搞清楚,什么是接口?多态的实现方式,举个最简单的例子。
    我声明一个IUser这样的接口,只有一个方法就是获取用户名称
    public interface IUser
    {
        string getUserName();
    }
    业务逻辑在使用时只对接口进行操作string UserName=user.getUserName();(user是IUser类型)
    好,假设我当前要实现的是对SqlServer进行操作读取用户名称
    public class SqlUser:IUser
    {
        public string getUserName(){....}
    }
    如果有一天要换成Oracle的话怎么办呢?如果是你的业务逻辑在调用用户名称都是针对接口编程的话,那么很简单,你只要加一个实现类和更改你的配置即可
    public class OracleUser:IUser
    {
        public string getUserName(){....}
    }
    你的业务逻辑一字也不用动。
      

  2.   

    接口的说法已经不仅仅局限在实现多重继承了. (特别是JAVA,已经达到疯狂阶段)那在.NET我们要使用接口最好的例子那就是 .Net Remoting, 部署在client端的只是一个接口(因为client端不需要有具体实现, 开发者也不希望把实现部分部署在client端)  把实现部分部署在server端. (最后总结一下~: 所谓JAVA疯狂的接口就是要把 使用者和实现者分离 -- 使用者看不到实现部分, 但可以使用就行.  实现者才是实现真正逻辑的实体类.  .NET中这种倾向还不是很严重)
      

  3.   

    lxwin01(阿幸) 的例子来说吧, 完全没必要使用接口. 
    这个IUser接口完全可以用虚类来代替. (这样和用interface有什么区别吗?? )public abstract class IUser
    {
        public abstract string getUserName();
    }
    public class SqlUser:IUser
    {
        public string getUserName(){....}
    }
    public class OracleUser:IUser
    {
        public string getUserName(){....}
    }
    (难道效果不同吗? 不可能~!~)
      

  4.   

    我也来说2句,类不可以多继承是有原因的(类如果可以多继承,那会是个什么样的世界啊),接口一般都是多继承也是有他自己的目的.以我个人对OO的理解,认为基础类用抽象类写,就是定义属性,方法.和这个类的接口.然后下面N多实现功能的子类(实际的代码都写在这些里面),如果逻辑有更改的时候就更改,或者添加这些继承类.而同时对于外部应用直接调用接口(根本不用考虑功能的实现问题.这里就涉及封装和多态的概念)楼主貌似有点钻牛角尖.首先说,要实现一个功能是简单的,但是要写得可维护才是好程序.如2楼说的意思.如你所说,就不从接口继承,从类继承,那么想想为什么抽象类和接口只能声明而不能实现?以上是我的一点OO心得,欢迎拍砖.
      

  5.   

    JasonHeung(拥有一切不过就这样笑着哭) 如果撇开多重继承的问题,虚基类和接口是同一个东西!=================================================我认为虚基类和接口如果不多继承,就没有概念他们的必要.直接用类return令一个类方法回去好了.
      

  6.   

    用了才知道,你不继承接口你能把对象转成(IInterface)obj吗,对于避免双向引用的问题时候这是很好的一个解决方法
      

  7.   

    实际用的多了,就明白怎么会事了,
    interface从名字去理解,是界面的意思,你可以理解成两个互不相关的东西的一个中介,
    ,所以也叫借口,从本质上说,真的和多重继承没有什么关系(个人理解)
    你可以当作一种协议,任何实现了一个interface的类,都可以当作实现了一个协议
    你调用interface的方法的时候,不要考虑具体是什么,而只要理解这个协议是什么。
    举一个简单的应用你开发了一个类库,你要使用一些资源比方说LOG用的,但是
    你不知道这个东西发布出去,用户会用在什么地方,你要想在内部实现你的
    logic,这个logic又要调用外部的资源(这个资源又是调用你的人实现)
    ,一个非常地好的办法就是你define一个
    interface,调用你的方法的程序必须实现这个interface,OK,这时候你就建立了
    从内部到外部的一个调用,而不用管最终用户到底是怎么实现这个interface的。从本质上说调用接口的方法应该是最快的。
      

  8.   

    如果你用Abstract抽象的话,由于是单继承,如果有一个抽象类既实现了UI的部分,也实现了功能部分(当然我是举个例子)如果你的开发UI部分不想暴露功能部分,使用接口
    interface UI
    {
        void show();
    }interface IUser
    {
        string getUserName();
    }Abstract absUser:UI,IUser
    {
        //实现它们
    }那么,给UI部分使用  (UI类型)userUi.Show();他并不知道有 getUserName这个方法。
    给功能 的部分 (IUser类型) user.getUserName();他不用关心有UI这个接口和去show()这只是一个小例子,当然有更好的方法去解决这些问题,如果深入些可以看看Ecilpse的无限扩展,用到其它的方法解决。
      

  9.   

    比如我们要做一个购书系统,购书后,需要进行打折,我们就来实现打折这一部分:using System;namespace InterfaceSample
    {
    // 表示一本书
    class Book
    {
    // 书名
    public string Name;
    // 价格
    public decimal Money;
    }
    //书价打折接口(接口就像一个协议,你不用知道协议后面是什么,只需要知道它遵守了这个协 议),在这里,我们只知道这个接口会进行打折计算
    interface IBookMoneyComputer
    {
    //计算书价
    /// <param name="books">要计算价格的书目</param>
    /// <param name="totalMoney">书的总价格(打折前的)</param>
    decimal Compute(Book[] books, decimal totalMoney);
    }//我们来实现两个打折器(构造两个类来实现IBookMoneyComputer接口)------------------
    // 总价打折器,只要书总价超过500, 我们就给它减去100
    class TotalMoneyComputer : IBookMoneyComputer
    {
    public decimal Compute(Book[] books, decimal totalMoney)
    {
    if (totalMoney > 500)
    return totalMoney - 100;
    return totalMoney;
    }
    }// 书类别打折器,只要有一本书名为"DotNet",我们就给总价减去50
    class BookTypeComputer : IBookMoneyComputer
    {
    public decimal Compute(Book[] books, decimal totalMoney)
    {
    foreach (Book book in books)
    {
    if (book.Name == "DotNet")
    return totalMoney - 50;
    }
    return totalMoney;
    }
    }//----------------------------------------------------------------class Class1
    {// 静态方法,接受一个book数组,和一个打折器,注意,我们这个参数是接口类型
    static decimal ComputeMoney(Book[] books, IBookMoneyComputer computer)
    {
    //注意,这里的计算打折前的总价程序不需要进行抽象
    decimal totalMoney = 0m;
    foreach (Book book in books)
    {
    totalMoney += book.Money;
    }
    //用接口类型进行打折,这样有很大的灵活性,可以随时更改打折策略
    return computer.Compute(books, totalMoney);
    }/// 应用程序的主入口点。
    [STAThread]
    static void Main(string[] args)
    {
    //我们来购造三本书
    Book book1 = new Book();
    book1.Name = "aaa";
    book1.Money = 200;Book book2 = new Book();
    book2.Name = "bbb";
    book2.Money = 400;Book book3 = new Book();
    book3.Name = "DotNet";
    book3.Money = 200;//可以分别运行两种打折策略来进行打折
    Console.WriteLine(ComputeMoney(new Book[] { book1, book2, book3 }, new TotalMoneyComputer()));Console.WriteLine(ComputeMoney(new Book[] { book1, book2, book3 }, new BookTypeComputer()));
    Console.Read();
    }
    }
    }
    在上面的代码,由其是Main方法的实现,这样写有什么好处?