4

每次我读到接口时,都会提到它没有任何数据成员或实现。

但是当我看到带有接口的代码时,它们两者都有。

class IInterface
{
public:
    IInterface(){}
    virtual ~IInterface(){}
    int getInt(){ return m_int; }
    virtual void Boo() = 0;
    int m_int;
};

class cInterface : public IInterface
{
public:
    virtual void    Boo()
                    {
                        printf( "defined in .cpp for readability\n" );
                    };
};

class cFoo : public cInterface
{
};

(几乎)我从来没有在源文件中看到它们,而只有标题。

这个术语的使用有多严格,如果上面不是接口,它是如何调用的?

将其用作 IInterface* 时是否反映了 cInterface/cFoo 的用法?

...
cFoo foo;
IInterface* object = &foo;
object->Boo();
...
4

3 回答 3

6

C++ 在其语言定义中没有接口类型的正式定义,也没有办法强制编写纯抽象类。然而,这个概念肯定存在于软件工程中,并且可以追溯到很长很长的路要走。Corba 和 COM 是典型的例子。通用技术称为“基于接口的编程”。另一个流行的标签是“按合同设计”。一些 C++ 编译器具有支持它们的语言扩展,例如 MSVC 中的 __interface。它在其他方面仍然是一个普通的类,编译器只是强制执行纯度。

一个具体的例子是使用一个接口来定义一个实际存在于另一个运行时环境中的对象的代理。就像在地球另一端的机器上一样。代理,接口的本地实现,具有在线路上发送参数值的方法。电线的另一端有一个带有实际方法的存根。如果对象实际上是在本地创建的,则客户端代码不需要任何更改,其主要优点是它仍然使用相同的接口。换句话说,实现是不可见的,不会影响代码。您给出的示例在这种情况下将无法正确运行,远程对象将没有正确的 m_int 成员值。它不是接口,只是一个抽象类。

接口在不实现多重继承的语言中尤其重要。由于钻石问题,MI 很困难。但这是一个实现继承问题,继承多个接口没有问题。这种语言必须解决的唯一小问题是当两个或多个继承接口具有具有相同名称和签名的方法时的歧义。但这可以通过为语言提供一种方法来指定正在实现的特定接口方法来轻松解决。就像 C# 中的“显式接口实现”语法一样。不确定Java是做什么的。

另一个既实用又麻烦的方面是它是设计工具,即“契约式设计”的角度。如果您与很多开发人员一起从事一个大型项目,那么您最终往往会得到很多接口。它们包含了建筑师发出的“这是我们应该做的”。但是没有任何“这就是我所做的”,尤其是在项目的早期。真正的错误是实现错误,很少是接口错误。一个真正让多个程序员同时工作的优秀工具。但是主要糟糕的是要让项目的基础健全并锁定,这样你就可以在上面进行构建。不是 Bjarne 的工作方式。

于 2012-08-11T21:17:15.743 回答
2

C++ 中对这个术语没有严格的定义。它通常松散地用来表示一个主要是抽象的类:一个定义交互协议而不是任何类型的实现的类。由于它不是语言中构建的概念,因此人们可以对定义不那么严格,并且数据有时会潜入“接口”。

然而,在某些编程语言和系统中——Java 是一个典型的例子——它是一种语言特性,并且具有非常正式的含义。在这些环境中,确切的含义当然是特定于环境的,但通常与上面讨论的大致相同。在 Java 中,接口是一种只有纯虚函数和编译时常量数据成员的类。Java 允许一个类只扩展另一个类,但一个类可以实现任意数量的接口。

于 2012-08-11T20:43:26.843 回答
0

简单地说,“接口”可以用来指代方法和/或数据——具体的或抽象的(例如virtual)。“接口”的更基本定义也经常用于指代您的实现可以访问的内容(例如,公共方法是公共接口的一部分)。

正如 Ernest 所指出的,您似乎在某些时候所期望的定义是 Java 的定义,而 Java 的定义则大不相同,因为它意味着非常具体的东西。Java 的接口表示/定义类似于 C++ 中的纯抽象类。

因此,“接口”不等同于 C++ 中的纯抽象类——它是一个更通用的术语,可用于指代对象声明的方法(虚拟或非虚拟)和基类(但不包括这些方法的定义)。我说,即使声明的 typedef 和常量也可以作为对象接口的一部分(特别是在模板元编程中);尽管我怀疑某些人的定义可能太过分了(实际上,接口在 C++ 中并没有严格定义——所以一个人的定义可能会因他们经常光顾的水坑而异)。

于 2012-08-11T22:08:01.717 回答