2009-08-27 76 views
2

最近有人在采访中被问到,一个接口可以被认为是C#中的一个类吗?即是一个接口是C#中的类吗?Class vs Interface

我很困惑。

可以回答什么?

+0

什么语言/环境? – SLaks 2009-08-27 01:33:55

+0

PLZ查看更新。 – anonymous 2009-08-27 01:36:02

回答

8

不,接口不是一个类。

一个接口是一组方法签名和可能属性,都涉及到一个单一的想法。例如,IList接口将具有索引,插入和获取元素数量的方法。但是,它没有定义任何实现细节。列表接口可以实现为链表或者封装数组,或者任何你想要的,只要它在接口中定义了这些方法即可。

类是从中创建实际对象的模板。类是方法签名的集合,以及这些方法的实现。

所以不,一个接口不是一个类,因为它只是定义了一个特定的契约,而一个类定义了该对象的整个行为。

评论员SquareCog准确地指出上述不完全正确。由于类可以被子类化,并且方法被覆盖,所以类与对象的实际行为的关系变得更加复杂。我只是想把这个问题说成是个别的实体。你可以阅读一个类的源代码,并且知道该类包含哪些行为。但是,在运行时,对象具有类型而不是类。类型是整个继承树,而不是单数类,因此类型的行为可以在几个不同的类上定义。幸运的是,这并没有改变基本的概念上的区别,即接口是可以暗示(通过名称,参数类型等)某些实现的契约,但不能强制执行除方法签名外的任何内容,而类确实定义了实现,即使这不是在运行时使用的实际实现。

+0

肖恩,这是一个很好的措辞答案。我会小心地说,一个类定义了对象的行为 - 可以扩展(继承)一个类并完全重写内部。所以只是因为你知道什么是Foo,并不一定意味着你知道它是如何实现的(它实际上可能是Bar,Foo的叛逆之子)。 – SquareCog 2009-08-27 01:51:55

+0

@肖恩,你的头像根本不适合你。 Plz考虑改变它。 – anonymous 2009-08-27 01:52:01

+0

@SquareCog:真的,我没有考虑到这一点。我会通过声明类是个体实体来解决它,每个实体定义一个特定的行为,然后实际的对象的行为实际上由它的类型定义,这是它的继承树的合并。这样,我不必更改我的帖子; P – Sean 2009-08-27 01:59:16

1

可能有几个答案。不,一个类不是一个接口 - 一个接口定义一个契约,一个类是一种可以创建的对象。

是的,只有虚拟方法才能将接口视为基类 - 这就是接口在C++中的定义方式。

2

是的,任何不包含实现且仅包含抽象方法的抽象类将等同于接口。

+2

根据语言的不同,它可能几乎相同但不完全相同:例如在C#中,一个类可以同时实现多个接口,但不能为一个以上的抽象类子类化。 – ChrisW 2009-08-27 01:38:09

+0

同意。我的“等值”并不意味着既不是'相同'也不是'是'。它只是意味着该类相当于一组核心接口属性的接口(尤其不包括多重继承)。 – topchef 2009-08-27 02:08:47

2

Java接口不是类;它是一个需要由类实现的方法声明;对能力的描述,如果你愿意的话。 Java中的抽象类是适当的类和接口之间的一个有趣的中间点,因为它们定义了可用的方法,但也提供了一些默认实现。

Java中抽象类和接口的根本区别在于,你只能扩展一个类;你可以实现多个接口。 抽象类描述你是什么;一个界面描述你可以做什么。你也定义你可以做什么 - 但它有更强的意义。

+2

Java与c#有什么关系? – 2009-08-27 01:41:38

+0

它们足够相似,概念成立 - 他所说的与C#相关的原因与Java相同。 – kyoryu 2009-08-27 01:44:01

+0

java和C#非常相似 – hhafez 2009-08-27 01:44:50

1

通常,接口是一种类型,可以通过类来实现,以表明该类通过一组方法公开行为。例如, 。Net有一个ICollection接口,其中包含与集合交互的方法。


在C++中,接口是一个类,每个方法都是抽象的。

在Java和.Net中,接口是与类无关的独立类型。

无论哪种方式,类可以实现接口。

3

从逻辑上讲,它们非常相似。正如其他人所指出的那样,只有公共抽象成员的ABC 与接口的功能几乎相同。

当您深入了解它的细节时,两者有许多重要的不同之处。

  • 一个类只能从一个基类继承,但可以实现多的接口。
  • 已从ValueType派生的值类型不能从ABC继承,但可以实现接口。
  • 一个类可以包含字段和静态成员。一个接口不能。
  • 一个类可以包含实现,但一个接口不能。
  • 一个类可以有私有和受保护的成员,但一个接口不能。
  • ABC的抽象成员总是虚拟的。一个类可以实现与非虚拟成员的接口。

1:抽象基类

0

它有助于把.NET为具有三个“安全”种类型在.NET:接口,类和值类型(也有像指针等等,但这些是另一个故事),并且可以使用三个主要上下文类:存储位置,堆对象和通用约束。

堆对象可以是任何类型,但所有堆对象的行为都与类对象相似。接口类型的堆对象很少;它们通常不是在.net内创建的,但可以通过设计用于使用旧对象模型的代码来创建。类类型的堆对象包含每个字段的一个存储位置;值类型的堆对象包含一个类型为相关值类型的存储位置。

存储位置同样可以是任何类型,但是值类型的存储位置与其他位置不同。类类型或接口类型的存储位置包含类引用。值类型的存储位置包含值原语(字节,整数,字符,浮点数等),或者包含值类型的每个字段的存储位置(例如,类型为Point的存储位置拥有类型为Int32的两个存储位置,每个存储位置都包含一个带符号的32位整数基元)。

通用约束也可以是任何类型,但接口类型的约束不会将约束泛型类型参数本身限制为类类型,接口类型或值类型。声明为void Foo<T>(T param) where T:IWowzo的方法可以使用类类型,接口类型或值类型的参数进行调用。如果使用值类型参数调用例程,则将param和声明为T类型的任何其他存储位置存储为值类型。如果使用类类型或整数类型的参数调用例程,则将param和声明为T类型的任何其他存储位置存储为类引用。值得注意的是,如果T本身就是一种接口类型(IWozo或衍生物),那么param将作为对堆对象的引用传递,并且无论对象实例的类型是类对象还是行为类似值类型。如果结构Bar实现IWowzo,并且myBarBar类型的变量,调用Foo<Bar>(myBar)可能产生与Foo<IWowzo>(myBar)不同的语义;在前一种情况下,参数将表现为值类型,在后一种情况下,它将表现为类类型。

相关问题