简体   繁体   English

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

[英]what's interface vs. methods, abstraction vs. encapsulation in C++

I am confused about such concepts when I discussed with my friend. 当我和朋友讨论时,我对这些概念感到困惑。

My friend's opinions are 我朋友的意见是

1) abstraction is about pure virtual function. 1)抽象是关于纯虚函数。

2) interface is not member functions, but interface is pure virtual functions. 2)接口不是成员函数,但是接口是纯虚函数。

I found that in C++ primer, interface are those operations the data type support, so member functions are interface. 我发现在C ++入门中,接口是数据类型支持的那些操作,因此成员函数是接口。

My opinions are 我的意见是

1) abstraction is about speration of interface and implementation; 1)抽象是关于接口和实现的扩展;

2) member functions are interfaces. 2)成员函数是接口。

So could anybody clarify these concepts for me? 那么有人可以为我澄清这些概念吗?

1) the difference among abstraction, abstract data type and abstract class. 1)抽象,抽象数据类型和抽象类之间的区别。

2) the difference between interface and member functions. 2)接口和成员函数之间的区别。

3) the difference between abstraction and encapsulation. 3)抽象和封装之间的区别。

I think your main problem is that you and your friend are using two different definitions of the word "interface", so you're both right in different ways. 我认为您的主要问题是您和您的朋友对“接口”一词使用了两种不同的定义,所以你们都以不同的方式正确。

You are using "interface" in the everyday sense of "a defined way to inter-operate with something", as in "the interface between my computer and my keyboard is USB" or "the interface between the vacuum and the wall power is an outlet." 您每天都在使用“接口”来定义“与某物进行互操作的定义方式”,例如“我的计算机和键盘之间的接口是USB”或“真空和墙壁电源之间的接口是一个出口。” In that sense, yes, methods (even concrete ones) are interfaces, since they define a way to inter-operate with an object. 从这个意义上讲,是的,方法(甚至是具体的方法)是接口,因为它们定义了与对象进行互操作的方式。 That's not to say that this is not applicable to software -- it is the sense of "interface" used in the term Application Programming Interface (API). 这并不是说它不适用于软件,而是术语“应用程序编程接口(API)”中使用的“接口”。

Your friend is using "interface" in the more specific object oriented programming jargon sense of "a separately defined set of operations that a class can choose to guarantee that it will support". 您的朋友在面向对象的编程术语中使用“接口”,即“一个类可以选择以保证它将支持的一组单独定义的操作”。 Here, the defining characteristic of an "interface" is that it has no implementation of its own. 在此,“接口”的定义特征是它没有自己的实现。 A class is supposed to support an interface by providing an implementation of the methods defined by the interface. 应该通过提供接口定义的方法的实现来支持一个接口。 Since C++ has no explicit concept of an interface in this sense, the equivalent construct is a class with only pure virtual functions (aka an Abstract Data Type). 由于C ++在这种意义上没有明确的接口概念,因此等效构造是仅具有纯虚函数(又称为抽象数据类型)的类。

"Abstraction", on the other hand, is about many things and again you are both right. 另一方面,“抽象”是关于很多事情的,而且你们俩都是对的。 Abstraction in a general sense means being able to focus on higher-level concepts rather than lower level details. 一般意义上的抽象意味着能够专注于较高级别的概念,而不是较低级别的细节。 Encapsulation is a type of abstraction because its purpose is to hide the implementation details of the methods of a class; 封装是一种抽象,因为其目的是隐藏类方法的实现细节。 the implementation can change without the class definition changing. 实现可以更改,而无需更改类定义。 Pure virtual functions ("interfaces" in the OO-jargon sense) are another type of abstraction because they can, if used properly, hide not only the implementation but also the true underlying object type; 纯粹的虚函数(OO术语中的“接口”)是另一种抽象类型,因为如果正确使用它们,它们不仅可以隐藏实现,而且可以隐藏真正的基础对象类型。 the type being used can change so long as both types implement the same interface. 只要两种类型都实现相同的接口,使用的类型就可以更改。

The same terms can be used for different things, which is what is happening here. 相同的术语可用于不同的事物,这就是在这里发生的事情。

"Abstract" in C++ means a method that doesn't have an implementation at all (you can't instantiate an object with Abstract members.) C ++中的“抽象”是指根本没有实现的方法(您无法使用抽象成员实例化一个对象。)

"Abstraction" is simply the concept of "modeling". “抽象”只是“建模”的概念。 Modelling is making something complex look simpler by ignoring some details. 建模通过忽略一些细节使复杂的事物看起来更简单。 In programming, you want to break operations and concepts up into components, and for each component, abstract away details about external components that don't affect the current component's operation. 在编程中,您希望将操作和概念分解为多个组件,并为每个组件抽象出不影响当前组件操作的外部组件的详细信息。

A programming "Interface" is a way of implementing "Abstraction". 编程“接口”是实现“抽象”的一种方式。 Rather than have all the source code and internal operations of a component, you only see the operations that are relevent to how you're using the object. 而不是拥有组件的所有源代码和内部操作,您只会看到与您如何使用对象有关的操作。 An "Interface" in C++ is implemented by marking all methods on a class as "abstract" (also called "pure virtual".) That's done by putting an '= 0' after the method declaration but before the semicolon. 通过将类上的所有方法标记为“抽象”(也称为“纯虚拟”)来实现C ++中的“接口”。这是通过在方法声明之后但在分号之前放置“ = 0”来实现的。 The method has to be marked 'virtual' for this to be legal. 该方法必须标记为“虚拟”才能合法。

In other words, an abstract C++ class is one that has at least one pure virtual method, and an interface is implemented in C++ by making all member functions pure virtual. 换句话说,抽象的C ++类是至少具有一个纯虚方法的类,并且通过使所有成员函数成为纯虚的方法在C ++中实现了接口。

Encapsulation is a fuzzy term, but to me it means a technique of implementing abstraction. 封装是一个模糊的术语,但对我而言,它意味着一种实现抽象的技术。 It means "information hiding". 这意味着“信息隐藏”。 You're hiding the internal details of how an object performs its "contract". 您正在隐藏对象如何执行其“合同”的内部细节。 The Contract is expressed through interfaces, which to my mind is a more powerful form of abstraction. 合同通过接口表达,我认为这是一种更强大的抽象形式。 Any C++ class with protected or private members uses encapsulation, but a class implementing only pure virtual methods is describing a contract, promising to deliver certain services for which you need to know absolutely nothing about how they are implemented or about other services the same object may implement. 任何具有受保护成员或私有成员的C ++类都使用封装,但是仅实现纯虚拟方法的类正在描述合同,承诺提供某些服务,而您对于这些服务的实现方式或同一对象可能提供的其他服务完全无需了解实行。

The same object may fill several contracts, and by exposing multiple, disjoint interfaces, it doesn't force clients to know about all of the auxilliary functions of the object. 相同的对象可能会履行多个合同,并且通过公开多个不相交的接口,它不会强制客户端知道该对象的所有辅助功能。 For example, an object may be able to tell you a bank account balance, and it also may be able to be serialized/deserialized to a database. 例如,一个对象可能能够告诉您银行帐户余额,并且还可以序列化/反序列化到数据库。 You could just have one class with all of those operations exposed as member functions. 您可能只有一个类,所有这些操作都作为成员函数公开。 I prefer to define two interfaces, 'IDatabaseSerializable' and 'IBankAccount', and put the appropriate operations in the appropriate interfaces and derive from both interfaces in my implementation class. 我更喜欢定义两个接口“ IDatabaseSerializable”和“ IBankAccount”,并将适当的操作放在适当的接口中,并从实现类中的这两个接口派生。 Then clients that only care about bank balances see as little extra information as possible, and the database only sees the operations that it cares about. 这样,仅关心银行余额的客户将看到尽可能少的额外信息,而数据库只会看到它关心的操作。

Virtual member functions (not neccessarily pure) in combination with inheritance are one way to express the concept of interfaces in C++, ie interfaces and methods are orthogonal concepts. 虚拟成员函数(不一定是纯函数)与继承相结合是表达C ++接口概念的一种方式 ,即接口和方法是正交的概念。

Another approach to interfaces in C++ is with generic code (ie templates), where you often don't expect any concrete type - instead you expect the type to have certain member functions with a certain semantic - if it doesn't you will get a compile error. C ++中接口的另一种方法是使用通用代码(即模板),您通常不希望任何具体类型-相反,您希望该类型具有具有某种语义的某些成员函数-如果不这样,您将获得一个编译错误。

Some people call this concepts and you talk of a type modelling a certain concept . 有人将其称为“ 概念”,而您谈到的是对特定概念建模的类型 Concepts are not formally supported in C++ though, but libraries like Boost.ConceptCheck do a pretty good job of providing a substitute. 虽然C ++并未正式支持概念,但是Boost.ConceptCheck之类的库在提供替代项方面做得很好。

  1. Abstraction means that someone can use your code without knowing about implementation details. 抽象意味着有人可以在不了解实现细节的情况下使用您的代码。 The thing that makes this complicated is that things that are implementation details in one context may not be in others. 使事情变得复杂的是,在一个上下文中作为实现细节的事物可能不在其他上下文中。 An abstract data type is a data type that cannot be instantiated and only describes attributes of its subtypes. 抽象数据类型是无法实例化的数据类型,仅描述其子类型的属性。 An abstract class is just something that's an abstract data type and a class. 抽象类只是某种抽象数据类型和类。

  2. An interface can be implicitly defined by a set of member functions (though to be a useful abstraction these should at least be virtual so that there is more than one possible implementation of the interface). 接口可以由一组成员函数隐式定义(尽管作为有用的抽象,这些成员函数至少应该是虚拟的,以便有多个可能的接口实现)。 It can also be defined explicitly as a class with only pure virtual functions (in C++) or an interface (in Java, C# and D). 也可以将其明确定义为仅具有纯虚函数(在C ++中)或interface (在Java,C#和D中)的类。

  3. Abstraction is when you don't have to know about the implementation details of something. 抽象是当你不必知道的东西的实现细节。 Encapsulation is when you can't know about them. 封装是当你无法知道它们。 For example, a class that is otherwise well-designed from an OO perspective, but doesn't bother setting its member variables to private can still be a useful abstraction, but it is not encapsulated. 例如,从OO角度出发,经过精心设计但又不麻烦将其成员变量设置为private仍然可以是有用的抽象,但不能进行封装。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM