类与接口

时间:2009-08-27 01:31:39

标签: c# class interface

最近我在接受采访时被问到,接口是否可以被视为C#中的一个类?即接口是C#中的一个类吗?

我很困惑。

答案是什么?

7 个答案:

答案 0 :(得分:8)

不,界面不是一个类。

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

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

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

Commenter SquareCog准确地指出上述情况并非完全正确。由于类可以被子类化,并且方法被重写,因此类与对象的实际行为的关系变得更加复杂。我只是通过说类是个体实体来解决这个问题。您可以阅读类的源代码并了解该类包含的行为。但是,在运行时,对象具有类型而不是类。类型是整个继承树,而不是单个类,因此可以在几个不同的类上定义类型的行为。幸运的是,这并没有改变接口是可以暗示(通过名称,参数类型等)某些实现的契约的基本概念差异,但是除了方法签名之外不能强制执行任何操作,而类确实定义了一个实现,即使这不是在运行时使用的实际实现。

答案 1 :(得分:3)

从逻辑角度来看,它们非常相似。正如其他人所指出的那样,只有公共抽象成员的ABC 1 与接口的用途几乎相同。

当你了解它的具体细节时,两者有许多重要的区别。

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

1:抽象基类

答案 2 :(得分:2)

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

答案 3 :(得分:2)

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

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

答案 4 :(得分:1)

可能有几个答案。

不,类不是接口 - 接口定义合约,类是可以创建的对象类型。

是的,可以将接口视为仅使用虚方法的基类 - 这就是在C ++中定义接口的方式。

答案 5 :(得分:1)

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


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

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

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

答案 6 :(得分:0)

将.net视为在.net中有三种“安全”类型是有帮助的:接口,类和值类型(还有像指针这样的东西,但那些是另一个故事),以及三个主要可以使用上下文类:存储位置,堆对象和通用约束。

堆对象可以是任何类型,但所有堆对象的行为都类似于对象。接口类型的堆对象很少见;它们通常不在.net中创建,但可以由设计用于较旧对象模型的代码创建。类类型的堆对象包含每个字段的一个存储位置;值类型的堆对象包含一个存储位置,其类型是有问题的值类型。

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

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