读书人

生手对接口 Interface,理解很吃力望

发布时间: 2013-02-24 17:58:57 作者: rapoo

新手对接口 Interface,理解很吃力,望前辈点拨
MSDN上只说“接口只包含方法、委托或事件的签名。方法的实现是在实现接口的类中完成的”
这句话我怎么看也没看出下面这段程序是如何体现接口的,下面的代码是摘自“c# 入门经典第三版".书中说也可以把值类型封箱到一个接口类型。这接口类型又是什么类型?那个IMyinterface refType = valType1 我没法理解,难道可以象定义类的引用那样定义一个类型的引用,而这个类型是个接口?这都是什么意思啊?



class Program
{

interface IMyinterface
{
}

struct MyStruct : IMyinterface
{
public int Val;
}


static void Main(string[] args)
{
MyStruct valType1 = new MyStruct();

IMyinterface refType = valType1;


MyStruct ValType2 = (MyStruct)refType;
}
}


[解决办法]
MyStruct继承了接口IMyinterface

但IMyinterface里没有要实现的方法,所以这样就行。


IMyinterface refType = valType1;
IMyinterface 是refType的父类,这样表示当然也行啊


[解决办法]
你给的代码是接口的特例,它是为了说明可以让值类型(结构体)继承一个接口。

一个类型,很明显,也是它的父类型。比如,男人继承自人,那么
男人 张三也可以是人 张三。

一个接口相当于一个抽象的基类。
[解决办法]
书中说也可以把值类型封箱到一个接口类型。

一种泛化说法。也没错。.net下,所有都是继承自Object。都是类型。
[解决办法]
比如

interface I驾驶技能
{
void DoDrive();
}

class Man
{
public virtual void DoEat(Food f) { ... }
public virtual void DoSleep() { ... }
}

class 驾驶员 : Man, I驾驶技能
{
public void DoDrive() { ... }
}

调用:
Man 张三 = new 驾驶员(); // 张三是一个驾驶员
I驾驶技能 drv = 张三; // 驾驶员有驾驶技能
[解决办法]
本帖最后由 caozhy 于 2011-04-03 09:42:09 编辑 .net和java不支持多重继承,此时只能使用interface。反过来说,当你设计一个应用接口,考虑到使用它的对象可能原来已经从其它class继承了,所以往往不得不使用interface来实现这个应用接口,因为java/.net不支持多重继承。
[解决办法]
注意,我上面不是在写概念,而是再说使用方面的问题。
[解决办法]
IMyinterface refType = valType1;

是不是写成 IMyinterface refType = valType1 as IMyinterface ;

更直观些?
[解决办法]
比如说,接着#5楼的例子,假设我们还要说明“驾驶员”继承自“中国公民”,那么就没有办法去继承作为class的中国公民了。尽管每一次都要去实现interface的接口令人痛苦,我们也不得不让驾驶员去继承自 I中国公民 这个interface,然后逐一手工实现这个接口的所有属性和方法,而无法使用class继承。



这是从实际编程的角度来说的,是说.net和java不支持多重继承的特性带来的副作用。从设计角度,class和interface都是一样的,都可以作为对象的分类来使用。甚至你在设计一个对象类的继承结构时,没有必要去搞清楚它的父类是class还是interface。在设计时它们的作用是一样的。

但是在编程时稍有区别。除了interface没有去实现任何代码继承以外,interface还不具有继承特点,也就是说如果你希望子interface也具有父interface,必须重复声明。而class支持继承,即子类自动具有父类多具有的interface。
[解决办法]

引用:
IMyinterface refType = valType1;

是不是写成 IMyinterface refType = valType1 as IMyinterface ;

更直观些?


这显然多花费几百行汇编语句、CPU时间去做无用功。valType1本来就是一个IMyinterface对象,本来就是,而不需要转换。
[解决办法]
代码
  MyStruct valType1 = new MyStruct();

IMyinterface refType = valType1;

它申明了两个变量,指向同一个对象。只不过这两个变量向编译器申明的类型是不同的而已。

两个变量指向同一个对象,不存在任何“转换”操作,不应该额外去写什么as代码。
[解决办法]
引用:
比如说,接着#5楼的例子,假设我们还要说明“驾驶员”继承自“中国公民”,那么就没有办法去继承作为class的中国公民了。尽管每一次都要去实现interface的接口令人痛苦,我们也不得不让驾驶员去继承自 I中国公民 这个interface,然后逐一手工实现这个接口的所有属性和方法,而无法使用class继承。

这是从实际编程的角度来说的,是说.net和java不支持多重继承的特性带来的副作用。……

但是我们可以使用聚合代替继承。
[解决办法]
引用:
但是我们可以使用聚合代替继承。


这个“代替”是编程角度,而不是真正的设计角度。

比如说在驾驶员类型中使用一个申明为中国公民类型的属性,这也许能够很笨拙地实现一些编程,但是没有能够直截了当地表达我们希望的“驾驶员是中国公民”的设计要求,因此对于多态等等基于面向对象方法的应用也都不支持。
[解决办法]
呵呵,习惯了,个人经常写一些控件,这些控件实现了不同的接口,

在控件的父控件中遍历子控件的过程中, 多用 as 来确定不同的接口

因为确定控件时返回的是 Control 类型 用as转化是合适的

这里直接定义了一个对象,确实是不需要 as


[解决办法]
假设控件x它继承自Control,那么我们可以直接写
Control y=x;

编译器可以正确地验证这个变量y的类型,并正确编译。

反过来,假设x是Control,我们想让程序在运行时去转换类型(而不是编译器去验证类型)并赋值给变量y,那么这时候才需要写as转换或者强制类型转换之类的代码!
[解决办法]
该回复于2011-05-08 23:21:22被版主删除
[解决办法]
引用:
这位专家,谢谢你的回复, 真该早点来这里向大家学习。我特别看到您提到:"但是在编程时稍有区别。除了interface没有去实现任何代码继承以外,interface还不具有继承特点,也就是说如果你希望子interface也具有父interface,必须重复声明。而class支持继承,即子类自动具有父类多具有的interface。"

我还没碰到过接口继承接口的例子,您能不能讲得具体点呢,如何做才是“希望子interface也具有父interface,必须重复声明”。 谢谢您花宝贵时间指导我。


这个么,希望楼主不要被误导了。interface不能被继承这个杜撰的观点或描述错误的观点不能记住。可以试试


public interface IInterface1
{
void Test1();
}

public interface IInterface2 : IInterface1
{
void Test2();
}


又或是不想试,看看系统的定义即可。


using System.Collections;
using System.Runtime.CompilerServices;

namespace System.Collections.Generic
{
// 摘要:
// 公开枚举数,该枚举数支持在指定类型的集合上进行简单迭代。
//
// 类型参数:
// T:
// 要枚举的对象的类型。


public interface IEnumerable<T> : IEnumerable
{
// 摘要:
// 返回一个循环访问集合的枚举数。
//
// 返回结果:
// 可用于循环访问集合的 System.Collections.Generic.IEnumerator<T>。
IEnumerator<T> GetEnumerator();
}
}



接口显然可以继承。

但sp1234不会说错的,猜测sp1234说的是显示实现接口不能通过继承具有实现接口特性的意思吧。
[解决办法]
一个人掏出一张中华人民共和国居民身份证,他就是中国公民,不管他是白人黑人...他掏出一张随便哪个国家的机动车行驶证,他就是驾驶员,不管他是中国人美国人...

接口是个契约,继承一个接口表明对象遵循该契约...

可以认为身份证是个接口,机动车行驶证也是接口...所以可以由接口识别对象,而不用去管对象的类型...具体在.NET中来说,对象实例可以被转换为继承链向下任一类型及接口,这就是“接口 XXX=某个引用”的原因...

至于多根而是单根继承,我觉得对楼主来说过早了...他显然还没有理解这些概念的基础知识,sp1234的很多高论其实初学者是很难甚至无法消化的...
[解决办法]
这里有有关接口的视频教程你参考下:http://book.duoe.net/soft/html/3243.html
接口其实就是一个开放的类,给他加上个特别的出口。也就多了个出口,你可以直接从开放类出来,也可以从接口出来。而且接口可以实现多元化,比如IDataReader这个接口可以实现各种数据库的类型,Sql,Access等
[解决办法]
明白多态就明白接口
所以从多态入手!!!

读书人网 >C#

热点推荐