IClass a = new ClassA();
 a.GetName();
你说你关心电是那个发电厂发的。
但是你的两条语句,就关心了。
假设,这两个语句是有不同的模块来使用就可以了。

解决方案 »

  1.   


    啥意思,我没看懂?
    我的意思是既然new的时候需要知道是哪个实现类,就说明没有办法屏蔽底层实现。
      

  2.   

    接口的作用:
    http://www.cnblogs.com/zhangzt/archive/2009/11/28/1612556.html
      

  3.   

    你一直都是只看眼前,不看后面。
    你上次那个问了3次也没结贴的问题就是太专注眼前,而非专注背后“管理类”
    同样这个问题基本也是一个问题“依赖倒置---对抽象编程,对类型编程,而非要强求一个具体实现”
    ok,我举个例子你就明白了
    验孕纸====人家设计验孕纸只关心你提供的检测样本,而不关心你new了那个gril你站在验孕纸个这个设计的角度,你觉着你应该关心new了那个gril么?所以俺们不管gril是谁,俺们就管样本本身,俺们只依赖抽象,甚至俺们都可以假装一个gril都没有,只是理论上样本应该如此就可以设计这个纸片了
      

  4.   


    这里面讲的东西我都明白,我的意思是这里
    IClass a = new ClassA();使用接口方法的时候,必须知道具体的实现类,而我们讲尽量屏蔽下层的实现,而你使用的时候又必须知道实现,岂不是违反了原则?
      

  5.   


    这里面讲的东西我都明白,我的意思是这里
    IClass a = new ClassA();使用接口方法的时候,必须知道具体的实现类,而我们讲尽量屏蔽下层的实现,而你使用的时候又必须知道实现,岂不是违反了原则?
    就拿你说的电厂来举例,我可以不知道电从哪里来,但是我起码得知道插座在哪里,是两项的还是三项的,是220V的还是110V的.
    IClass a = new ClassA();这个也一样.我可以不去管CLASSA是从哪里来的,但是我必须知道我要实现的是什么,里面都有什么方法
      

  6.   

    接口其实是用来将依赖倒置的,LZ钻在“顺序依赖”的胡同里出不来了
    你不需要知道对方给你的是A还是B,就能够用接口调用到它的内部实现这不挺好
    GetName(IClass item) { reture item.GetName(); }如果没有接口或上层抽象,就可能需要这样写,因为item有可能是别的程序传给你的,你压根就不知道具体类型
    GetName( object item)
    {
            if(item is A) 
                      return (item as A).GetAName();
            else if(item is B)
                      return (item as B).GetBName();
             ....
    }
           
      

  7.   


    请问,从实际出发,如果我需要知道调用哪个实现的话,那么所谓的扩展是怎么实现的?我新定义一个方法也是一样的啊!你不用管是哪个电厂给你发电,是因为你不用直接调用电厂,而是供电局帮你new电厂。
    相当于隔了1层,你---接口---供电局---接口---电厂。接口定义了规范,为什么要定义规范,就是为了减少变化,软件系统很怕变化。用了接口后,规范不变,但是实现可以变,大大增加了程序的弹性。
      

  8.   


    这样的做法本身没什么问题,也被广泛采用,
    但是绝对不是什么依赖倒置,因为这样就必须要求提供者是XXX类型
    依赖倒置是:由调用者实现接口,通过构造函数注入给提供者,提供者使用接口,
    通过接口开放的事件,就能让提供者"随时"提供服务,而不需要由调用者显示调用提供者的方法
    这样的话,就不需要知道提供者是什么类型了
      

  9.   

    其实你的问题没什么深奥的,你只要理解这么一个简单的道理就行了。在一个程序中,不同部分的源代码是不同的人写的(而不是和你在学校一样,所有的程序都是一个人写的)。因此写一部分的人定义了接口类型。而写另一部分的人(调用者)实现接口,并且传给那个人写的程序。比如说一个人(这个人叫微软)写了一个SortedList,提供了通用的排序列表。另一个人(比如你)写了一个类,实现ICompareable,传给它,实现对指定字段的排序。这无关什么工厂模式。
      

  10.   

    接口为什么叫接口,因为跟硬件的接口有共通之处.
    比如电脑上有USB接口,电脑厂家只要定义好这个接口,设备厂家去实现这个接口
    我这个USB就可以插入任何有USB的设备,然后你只要通过驱动告诉电脑你里面怎么调用,而电脑不需要知道设备里到底怎么实现的.否则就变成每个设备提供一个特定的类型,然后电脑要用就得安装不同的外部设备,变成一个怪物.
      

  11.   

    我后来想了想,其实我个人觉得,接口更加像是一种软件规范。就像caozhy版主说的,软件是由不同的人来写的,我必须严格定义每一个人要写的东西,接口提供了这样一种可能,就是不管你怎么写,你必须实现我这些功能,其实这个东西和业务无关。就是规范,规则,我用接口告诉你必须实现这些东西,如果你不实现,是不行的。但如果单独设置类或者方法,则没有办法实现对其它具体写软件的人的约束了,他如果不写某些方法,则会造成整个系统的崩溃,而接口则限制了他必须完成。所以我认为,接口是对软件人员交互之间的规范。
      

  12.   

    对啊.就像USB口,设备不是USB口,你就不能插在电脑上,想接入电脑,你就必须实现USB口.
    电厂的例子里,插座就是接口.你必须符合某种规范,不能就给我提供俩孔让我用两根电线去捅.
      

  13.   

    在你new classA/B/C时,你就是发电厂。你想发220V的还是110V的,你肯定要先知道
    至于怎么用电,是后面的事,不用你操心。你也管不着。
      

  14.   


    这样的做法本身没什么问题,也被广泛采用,
    但是绝对不是什么依赖倒置,因为这样就必须要求提供者是XXX类型
    依赖倒置是:由调用者实现接口,通过构造函数注入给提供者,提供者使用接口,
    通过接口开放的事件,就能让提供者"随时"提供服务,而不需要由调用者显示调用提供者的方法
    这样的话,就不需要知道提供者是什么类型了
    看来你也有点过于纠结了,不要一提依赖倒置就扯什么注入啊事件之类的
    倒置是什么意思呢?
      

  15.   

    接口就是一种规范,你定义一个接口,别人实现就必须根据你的接口定义的规范来。
    比如,电脑的USB接口,硬件厂商缺做的PS/2的接口,怎么办?
      

  16.   


    接口--基类--子类;
    接口定义规范;基类包含你说的通用实现,非通用实现,可以写成抽象方法或者虚方法;子类不需要重写通用方法,只需要重写抽象方法或者虚方法。书上说的角度不同,着眼点不同,是从比较大的层面来说。你说的是比较小的实现。从高层次看,很多东西都是接口问题,api问题。
      

  17.   

    1.是你先提到了依赖倒置,而你给出的代码和思路却恰恰是你自己反对的"顺序依赖";
    2.回答你的问题:
      你设计这样一个接口,使得调用者和提供者在角色上反转,
      这样的话,提供者成了接口的使用者,他是什么类型就无所谓了;
    3.你那种写法作为编程手段无可厚非,但是不能作为设计手段,
      很多人因为需要GetName这个方法,就弄个Iclass.GetName,这种接口只是编程意义上的接口,
      而不是设计意义上的接口,它太具体了,没有什么重用价值,从而导致依赖这些接口的组件也没有重用价值,
      不仅如此,到处都是接口还增加了代码量
      

  18.   


    不知道这是什么书。我想它非常容易产生误解。不管是interface还是class,只要是被你的class继承或者使用,你都可以看成是逻辑意义上的接口。只不过使用interface确实经常产生”痛苦“的体验,因为需要费力气去手写补充的一堆代码,不像class继承直接就自动化实现了。但是.net和java都不支持多重继承,因此很尴尬地是,假设一个class已经有父类class了,它就不可能再继承其它的class,你不得不只能让其使用其它的interface,才能实现面向对象的继承和多态特性。比如说 SqlDataReader,它继承了 DbDataReader,那么就无法继承 SqlDataRecord 类。于是只好尴尬地让 SqlDataReader 使用 IDataRecord,来达到能够多态地用于各种 DataRecord 应用类库的目的。显然这是费力的,但是这是历史造成的。是上个世纪末那个时代造成的。不能不成为微软首先选择了模仿java。
      

  19.   

    不能不成为微软首先选择了模仿java  -->  不能不承认(那个时期)微软首先选择了模仿java如果一本书上猛然来一句”最好使用接口来实现“,我认为这是非常不负责任的,是给中专生办编程入门培训班的那种教学方法。假设稍微高级一点的课程和书籍,会比较可靠地基于.net源代码来分析,而不会随便道听途说。而打开.net framework源代码你会发现,凡是可以用继承的地方,几乎全都是优先使用了继承。12年前的.net framework本身,也没有你说的这本书上写的这种论调。
      

  20.   


    接口--基类--子类;
    接口定义规范;基类包含你说的通用实现,非通用实现,可以写成抽象方法或者虚方法;子类不需要重写通用方法,只需要重写抽象方法或者虚方法。书上说的角度不同,着眼点不同,是从比较大的层面来说。你说的是比较小的实现。从高层次看,很多东西都是接口问题,api问题。根据我昨天一天的自我思考,也是采用了你说的这种方法:接口-基类-子类
    不仅如此,我还想到了,如果基类如果给了实现,子类有可能不去实现的问题,后来又查找资料,得到一种解决方法:
    基类关于接口的实现全部采用抽象函数,然后在基类中给一个默认的实现函数,在子类中调用基类的实现函数,这样还可以避免某些子类在不清楚的情况下,没有给予合适的实现。
      

  21.   

    1.是你先提到了依赖倒置,而你给出的代码和思路却恰恰是你自己反对的"顺序依赖";
    2.回答你的问题:
      你设计这样一个接口,使得调用者和提供者在角色上反转,
      这样的话,提供者成了接口的使用者,他是什么类型就无所谓了;
    3.你那种写法作为编程手段无可厚非,但是不能作为设计手段,
      很多人因为需要GetName这个方法,就弄个Iclass.GetName,这种接口只是编程意义上的接口,
      而不是设计意义上的接口,它太具体了,没有什么重用价值,从而导致依赖这些接口的组件也没有重用价值,
      不仅如此,到处都是接口还增加了代码量算了,我说错了
    我也没说我反对什么"顺序依赖";,我只是说LZ在理解的时候跳不出这个思维定式
    恰恰相反,在实现开发中,我对接口的使用很谨慎,因为我也很懒
      

  22.   

    1.是你先提到了依赖倒置,而你给出的代码和思路却恰恰是你自己反对的"顺序依赖";
    2.回答你的问题:
      你设计这样一个接口,使得调用者和提供者在角色上反转,
      这样的话,提供者成了接口的使用者,他是什么类型就无所谓了;
    3.你那种写法作为编程手段无可厚非,但是不能作为设计手段,
      很多人因为需要GetName这个方法,就弄个Iclass.GetName,这种接口只是编程意义上的接口,
      而不是设计意义上的接口,它太具体了,没有什么重用价值,从而导致依赖这些接口的组件也没有重用价值,
      不仅如此,到处都是接口还增加了代码量什么是设计意义上的接口?
      

  23.   

    接口只是一个比较低级的表现形式。真正的所谓”面向接口进行程序设计“方法,是指使用了一套测试规范来预先定义出了组件的行为、功能。不是针对具体实现,但是一定是从外部定义出了”验收标准“。所以不要为了接口而接口,不要仅仅注重一个形式,要从逻辑含义上去应用接口,内容大于形式。接口就是合同,使用合同的人如果是那种只会满足合同中个别字眼的”小人“,那么这个合同就很容易会被违背。如果使用合同的人注重合同你的完整的需求,那么这个合同就很容易执行。因此虽然合同并不等于实现,但是合同对实现的”内涵“具有约束力。绝不能任意歪曲合同上的文字。如果你说”因为10个类中都有一个GetName方法,所以就发明一个XXXXX接口“,那么这种脱离了内容的生编乱造接口、为了接口而接口,是没有好处的。你就应该给10个类各自实现一个GetName方法,根本谈不上什么接口。
      

  24.   

    如果你不是死扣字眼去理解,而是从应用去理解,那么使用接口原本就是I充电设备 x = new 手机("XE354-8");
    myGate.送电(x);
    I充电设备 y = new 电瓶车("YT-1");
    myGate.送电(y);
    原本就是这样使用接口的。除非你根本不去管最终应用方法,满脑子只有理论。
      

  25.   


    -----------
    讲尽量屏蔽下层的实现,而你使用的时候又必须知道实现----------说法错误
    -------------
    接口其实是 3个方面:接口本身定义、接口的实现、接口的使用
    IClass a = new  ClassA() 是接口的使用,这里不存在你说的必须知道实现,这里还是不知道实现
    实现是“inherit”。使用的“人”和实现(制造)的“人”不是一个人。你可以买个ClassA工厂的插座
    IClass a = new  ClassA() ;也可以买个 ClassB 工厂插座
    IClass b = new  ClassB() ;还可以买个 ClassC工厂 插座
    IClass c = new  ClassC() ;只要你买的规格参数一样,不论是 a,b,c ,你都可以使用那个标准的接口方法GetName来充电。
    但你不知道 他内部到底怎么来实现的。