什么是接口与方法,抽象与封装在C ++中

时间:2010-01-22 20:34:21

标签: c++ oop

当我和朋友讨论时,我对这些概念感到困惑。

我朋友的意见是

1)抽象是关于纯虚函数。

2)接口不是成员函数,但接口是纯虚函数。

我发现在C ++入门中,接口是那些支持数据类型的操作,所以成员函数是接口。

我的意见是

1)抽象是关于接口和实现的准备;

2)成员函数是接口。

那么有人可以为我澄清这些概念吗?

1)抽象,抽象数据类型和抽象类之间的区别。

2)界面和成员函数之间的区别。

3)抽象和封装之间的区别。

4 个答案:

答案 0 :(得分:5)

我认为你的主要问题是你和你的朋友正在使用“界面”一词的两个不同定义,所以你们两种方式都不同。

您在日常意义上使用“界面”“以某种方式与某些东西进行互操作”,如“我的电脑与键盘之间的接口是USB”或“真空与墙壁之间的接口”权力是一个出路。“从这个意义上讲,是的,方法(甚至具体的方法)是接口,因为它们定义了一种与对象互操作的方式。这并不是说这不适用于软件 - 它是应用程序编程接口(API)一词中使用的“接口”。

你的朋友在更具体的面向对象编程行话中使用“接口”的意思是“一个类可以选择保证它将支持的一个单独定义的操作集”。这里,“接口”的定义特征是它没有自己的实现。通过提供接口定义的方法的实现,类应该支持接口。由于C ++在这个意义上没有明确的接口概念,因此等效构造是一个只有纯虚函数的类(也就是抽象数据类型)。

另一方面,“抽象”涉及很多事情,你们两个都是对的。一般意义上的抽象意味着能够专注于更高级别的概念而不是更低级别的细节。封装是一种抽象,因为它的目的是隐藏类方法的实现细节;如果没有更改类定义,实现可以更改。纯虚函数(OO-jargon意义上的“接口”)是另一种抽象类型,因为如果使用得当,它们不仅可以隐藏实现,还可以隐藏真正的底层对象类型;只要两种类型都实现相同的接口,所使用的类型就可以改变。

答案 1 :(得分:3)

相同的术语可以用于不同的事情,这就是这里发生的事情。

C ++中的“Abstract”表示一个根本没有实现的方法(你不能用Abstract成员实例化一个对象。)

“抽象”只是“建模”的概念。通过忽略一些细节,建模使复杂的东西看起来更简单。在编程中,您希望将操作和概念分解为组件,并且对于每个组件,抽象出有关不影响当前组件操作的外部组件的详细信息。

编程“接口”是实现“抽象”的一种方式。您只能看到与您使用该对象的方式相关的操作,而不是拥有组件的所有源代码和内部操作。 C ++中的“接口”是通过将类上的所有方法标记为“抽象”(也称为“纯虚拟”)来实现的。这是通过在方法声明之后但在分号之前放置'= 0'来完成的。该方法必须标记为“虚拟”才能合法。

换句话说,抽象C ++类是至少有一个纯虚方法,并且通过使所有成员函数都是纯虚拟的,用C ++实现接口。

封装是一个模糊的术语,但对我来说,它意味着一种实现抽象的技术。它意味着“信息隐藏”。您隐藏了对象如何执行其“合同”的内部细节。契约通过接口表达,在我看来,这是一种更强大的抽象形式。任何带有受保护或私有成员的C ++类都使用封装,但是只实现纯虚方法的类正在描述一个契约,承诺提供某些服务,您需要完全了解它们的实现方式以及相同对象可能涉及的其他服务。实行。

同一个对象可以填充多个契约,并且通过暴露多个不相交的接口,它不会强制客户端知道对象的所有辅助功能。例如,对象可能能够告诉您银行帐户余额,并且还可以将其序列化/反序列化为数据库。你可以只有一个类,所有这些操作都作为成员函数公开。我更喜欢定义两个接口,'IDatabaseSerializable'和'IBankAccount',并将适当的操作放在适当的接口中,并从我的实现类中的两个接口派生。然后,只关心银行余额的客户看到尽可能少的额外信息,数据库只能看到它关心的操作。

答案 2 :(得分:1)

虚拟成员函数(不一定是纯粹的)与继承相结合是单向来表达C ++中接口的概念,即接口和方法是正交概念。

C ++中接口的另一种方法是使用通用代码(即模板),在这种情况下,您通常不会期望任何具体类型 - 相反,您希望类型具有某些具有某种语义的成员函数 - 如果不是您将收到编译错误。

有些人称这个概念,你谈到一种建模某种概念的类型。但是,C ++中没有正式支持概念,但像Boost.ConceptCheck这样的库在提供替代方面做得非常好。

答案 3 :(得分:1)

  1. 抽象意味着有人可以在不知道实施细节的情况下使用您的代码。使这种复杂化的事情是,在一个上下文中作为实现细节的东西可能不在其他上下文中。抽象数据类型是无法实例化的数据类型,仅描述其子类型的属性。抽象类只是一种抽象数据类型和类。

  2. 接口可以由一组成员函数隐式定义(虽然它们是一个有用的抽象,但至少应该是虚拟的,这样才能有多个可能的接口实现)。它也可以明确定义为只有纯虚函数(在C ++中)或interface(在Java中,C#和D中)的类。

  3. 抽象是指您必须了解某些内容的实现细节。封装就是当你不能了解它们时。例如,一个从OO角度精心设计的类,但不打扰将其成员变量设置为private仍然可以是一个有用的抽象,但它不是封装的。