-
Abstract VS Encapsulation
Hi guys,
What is the difference betweeb Abstract And Encapsulation?
As far as I understood Abstraction relates to the idea of hiding data that are not needed for presentation.
Is that not the definition for Encapsulation?
Or I've got it all wrong?
Thank you for your help
-
Re: Abstract VS Encapsulation
From what I understand, abstraction and encapsulation are very much related. Abstraction involves some kind of hiding, or even just ignoring, of details (e.g., turning a set of related statements into a function, grouping a set of related functions into a class, creating a hierarchy out of a set of classes, thus inheritance is a kind of abstraction). Encapsulation is more specifically data hiding, or providing a set of functions such that the underlying data (and related private functions) that is the implementation detail of this set of functions is hidden or at least unavailable for direct access.
-
Re: Abstract VS Encapsulation
Abstraction is the process of hiding implementation detail by specifying behaviour only and leaving it to derived classes to decide how the behaviour will actually be implemented. From this we get polymorphic behaviour
Encapsulation is also about hiding implementation detail (sort of...) by making it inaccessible to calling code.
In both cases, the benefit is that calling code is restricted in its dependency on implementation detail, so is more robust in the face of change.
You can think of abstraction as being loosely allied to the IS-A relationship and encapsulation to the USES relationship.
-
Re: Abstract VS Encapsulation
I liked one of the articles by Andrew koening on abstraction. He said abstraction is "selective ignorance". You choose to ignore the details of implementation be it in context of exposing interfaces/abstract classes in OOP or just plain functions or files or whatever that helps you categorize various components into independent entities that can take up some responsibility to add up to provide the complete behaviour expected of a system. It is above taking up a responsibility by a module/component/class/structure/function in itself and ignoring the details of how it will be actually implemented or implementation of any relationship/dependencies with other entities. Just that component and the functionality that it would provide. For example, when you are reading this post of mine, you are just reading and probably thinking about what I have said and not about where I am from (well, you might have started to think that now... <pause> well, now, for sure) or where did I send this post from, how codeguru works and what not. You just ignore those things when you are reading this post. That is abstract thinking and your mind is applying that abstraction.
In technology, when designing applications, it is not always possible that you think that way. The thinking becomes dirty by worrying about too many details all at the same time which might be needed but not for the specific task you want to accomplish. This is all part of the divide and rule policy that helps divide a particular task into contributing components and integrating them to build up the whole thing. That is what is abstraction. Not really about hiding the implementation details but ignoring them. The hiding is what is called encapsulation. In C, that could be done by typedefs, file scope entities (using static). In C++ and other OOP supporting languages using private/protected/public/internal/default access specifiers. Encapsulation is about hiding unncessary details that might change or might cause strong coupling between entities or the details which are not really required by other components to achieve what they take ownership of; which is never found to be beneficial.
Hope this helps.
-
Re: Abstract VS Encapsulation
Abstraction is the process of taking a concept or idea, and being able to turn that concept from an idea into code. Bring alive your ideas from your mind, to paper, to source code, to exectuable code is abstraction.
Encapsulation is the process of organizing your data structures and classes to get the job done. Use common sense: "The project is entirely encapsulated in one module."
The correct term for hiding implementation, is called black boxing. That is, the process of exposing only a certain set of interfaces to the client, and hiding the implementation details from the client as well.
-
Re: Abstract VS Encapsulation
See this thread as well - abstraction. There the Leg and LivingThing are few examples of abstractions in the sense of abstract classes/concepts. The concrete classes form an abstraction in a sense as well in the context of the problem that is being solved by that application. The interfaces there are not very meaningful but should give you a good idea about what is being tried out.
-
Re: Abstract VS Encapsulation
-
Re: Abstract VS Encapsulation
Data Abstraction vs Encapsulation:
Data Abstraction increases the power of a programming language by creating user defined
data types. Using an OOP Language, one can abstract the details of a real-life entity and
hence forth simplify the implementation of a project by taking care of what the real-life
entity is supposed to do and how it can be used by the other entities without actually going
into the details of how the entity needs to be implemented.
In the above explanation, I refer to an object as a real-life entity. And objects serve the
purpose of abstracting the details of the implementation in the context of a project
implementation.
Encapsulation - is more to do with implementation details of how the abstraction is
fulfilled.
The class struct and the object instance together make encapsulation and data abstraction possible in an OOP language.
In short , abstraction ~ specification of what the object/class is supposed to do.
and encapsulation ~ is how to achieve it.
Regards,
Advika
-
Re: Abstract VS Encapsulation
Quote:
Originally Posted by
Salvadoravi
What is the difference betweeb Abstract And Encapsulation?
When you encapsulate something you get an inside and an outside. The outside is called (data) abstraction and the inside is called information hiding.
In practical programming terms the major mechanism for encapsulation is the class. The data abstraction is the public interface of the class the user sees (also called the type), and the hidden information is the non-public implementation of the class the user cannot see.
-
Re: Abstract VS Encapsulation
My view is that encapsulation is one of the means of achieving abstraction. Abstraction is simply a matter of reducing a complex task to a simple, logical set of commands (object public methods, for instance).
-
Re: Abstract VS Encapsulation
For me abstraction means finding commonality in generality. Like vehicle is the generality and one commonality to vehicles is the ability to move. Another commonality would be refuel. This allows client code to deal in vehicles generally and tell them to move and to refuel but the client code is unaware of how the moving and refueling is taking place. Which brings us to encapsulation. Encapsulation is taking the specific implementations of the commonalities in generality and hiding them away from client code.
-
Re: Abstract VS Encapsulation
Abstraction is the idea that the class works in the way you want it to work. Encapsulation hides all the nasty translation of that abstraction into the bits you have to use to do it.
-
Re: Abstract VS Encapsulation
Is it the second round now? :)
Well, nice try everybody but here comes the definite definitions (used in OO programming):
* Encapsulation is the idea of separating type and implementation from each other so they can be considered separately. The type is the outside view of an encapsulated entity. Hidden inside lurks the implementation, a specific realization of the type.
* Abstraction is the process of defining a type. The type is used to declare variables which hold data and therefore a type is also called a data abstraction.
-
Re: Abstract VS Encapsulation
Quote:
Originally Posted by _uj
Is it the second round now?
Who won the first round? :)
Quote:
Originally Posted by _uj
here comes the definite definitions (used in OO programming):
As much as I like your definitions, that sounds like a bold claim. On what grounds do you say that they are "the definite definitions" with respect to OO programming instead of merely being your definitions?
-
Re: Abstract VS Encapsulation
Quote:
Originally Posted by
JamesSchumacher
Abstraction is the process of taking a concept or idea, and being able to turn that concept from an idea into code. Bring alive your ideas from your mind, to paper, to source code, to exectuable code is abstraction.
Encapsulation is the process of organizing your data structures and classes to get the job done. Use common sense: "The project is entirely encapsulated in one module."
The correct term for hiding implementation, is called black boxing. That is, the process of exposing only a certain set of interfaces to the client, and hiding the implementation details from the client as well.
And yes I know that the ITERATOR code is incorrect, that's supposed to be the general iterator, I got in a hurry!
I have debugging the code I am working on as I work on it, and since I just started declaring the tree stuff, I haven't implemented it, so no debugging. For some reason I made a general iterator (implementation wise) when I implemented the tree iterator. =/
Code:
/////////////////////////////////////////////
/// (C) 2009 James Schumacher
/////////////////////////////////////////////
#ifndef CORE_COLLECTIONS_HPP_INCLUDED
#define CORE_COLLECTIONS_HPP_INCLUDED
#include <pshpack1.h>
namespace CppCore
{
namespace Collections
{
template <typename Type> class Vector
{
public:
/// Constants
enum ValueConstants
{
DefaultBlockSize = 64
};
Vector();
Vector(unsigned long dwCapacity,unsigned long dwBlockSize);
Vector(const Type * pArrayData,unsigned long dwStart,unsigned long dwCount);
Vector(const Vector<Type> & arData);
virtual ~Vector();
/// Member Functions
inline unsigned long GetCapacity() const { return m_dwCapacity; }
inline unsigned long GetBlockSize() const { return m_dwBlockSize; }
inline unsigned long GetSize() const { return m_dwCount; }
inline const Type * GetData() const { return m_pArrayData; }
inline Type * GetBuffer() { return m_pArrayData; }
inline void ReleaseBuffer(unsigned long dwCount) { m_dwCount = dwCount; }
inline void Clear() { m_dwCount = 0; }
bool SetCapacity(unsigned long dwCapacity,bool bKeepData);
/// Overloaded Operators
Vector<Type> & operator = (const Vector<Type> & arData);
inline const Type & operator [] (unsigned long dwIndex) const { return m_pArrayData[dwIndex]; }
inline Type & operator [] (unsigned long dwIndex) { return m_pArrayData[dwIndex]; }
protected:
/// Member Variables
Type * m_pArrayData;
unsigned long m_dwCapacity;
mutable unsigned long m_dwBlockSize;
unsigned long m_dwCount;
/// Member Functions
unsigned long DetermineCapacity(unsigned long dwCount) const;
};
/////////////////////////////////////
/// NOTE: NodeType for List
/// Must have two member variables
/// in NodeType of pointers to
/// to a NodeType, they must be
/// named NextListNode and
/// PreviousListNode
/// See the default base
/// list type for an example.
/////////////////////////////////////
template <typename Type> class ValueListNode
{
public:
inline ValueListNode() : NextListNode(0),PreviousListNode(0),m_udtValue() {}
inline ValueListNode(const ValueListNode<Type> & udtValue) : NextListNode(0),PreviousListNode(0),
m_udtValue(udtValue.m_udtValue) {}
inline virtual ~ValueListNode() {}
inline const Type & GetValue() const { return m_udtValue; }
inline Type & GetValueReference() { return m_udtValue; }
inline void SetValue(const Type & udtValue) { m_udtValue = udtValue; }
inline ValueListNode<Type> & operator = (const ValueListNode<Type> & arData)
{
if (this != &arData)
{
m_udtValue = arData.m_udtValue;
}
return *this;
}
public:
ValueListNode<Type> * NextListNode;
ValueListNode<Type> * PreviousListNode;
protected:
Type m_udtValue;
};
template <typename NodeType> class List
{
public:
List();
List(const List<NodeType> & udtList);
virtual ~List();
void Add(NodeType * pNode);
void Remove(NodeType * pNode,bool bDelete);
void Clear();
inline const NodeType * GetStart() const { return m_pStart; }
inline NodeType * GetStart() { return m_pStart; }
inline const NodeType * GetEnd() const { return m_pEnd; }
inline NodeType * GetEnd() { return m_pEnd; }
inline unsigned long GetSize() const { return m_dwCount; }
inline bool WillDeleteNodes() const { return m_bDeleteNodes; }
inline void SetDeleteNodes(bool bDelete) { m_bDeleteNodes = bDelete; }
List<NodeType> & operator = (const List<NodeType> & udtList);
protected:
NodeType * m_pStart;
NodeType * m_pEnd;
unsigned long m_dwCount;
bool m_bDeleteNodes;
};
template <typename Type> class IComparer
{
public:
IComparer() {}
virtual ~IComparer() {}
virtual long Compare(const Type & obj1,const Type & obj2) const = 0;
virtual bool Equal(const Type & obj1,const Type & obj2) const = 0;
virtual bool NotEqual(const Type & obj1,const Type & obj2) const = 0;
};
template <typename Type> class Comparer : public IComparer<Type>
{
public:
enum ErrorCodes
{
CompareError = -15
};
Comparer() {}
virtual ~Comparer() {}
virtual long Compare(const Type & obj1,const Type & obj2) const
{
long nRetValue = CompareError;
if (obj1 < obj2)
{
nRetValue = -1;
}
else if (obj1 > obj2)
{
nRetValue = 1;
}
else if (obj1 == obj2)
{
nRetValue = 0;
}
return nRetValue;
}
virtual bool Equal(const Type & obj1,const Type & obj2) const
{
return obj1 == obj2;
}
virtual bool NotEqual(const Type & obj1,const Type & obj2) const
{
return obj1 != obj2;
}
};
template <typename UDTValue> class ValueTreeNode : public ValueListNode<UDTValue>
{
public:
typedef ValueTreeNode<UDTValue> NodeType;
inline ValueTreeNode() : ValueListNode<UDTValue>(),ParentTreeNode(0),
LessTreeNode(0),GreaterTreeNode(0),EqualList(),
TreePriorNode(0),NextNode(0),DeleteMe(true) {}
inline virtual ~ValueTreeNode() {}
/// Member Variables
NodeType * ParentTreeNode;
NodeType * LessTreeNode;
NodeType * GreaterTreeNode;
List<UDTValue> EqualList;
NodeType * TreePriorNode;
NodeType * NextNode;
bool DeleteMe;
};
template <typename NodeType> class TreeNodeIter
{
public:
TreeNodeIter() : m_pBase(0),m_dwOffset(0) {}
TreeNodeIter(const NodeType * pNode) : m_pBase(const_cast<NodeType *>(pNode)),m_dwOffset(0) {}
TreeNodeIter(const TreeNodeIter<NodeType> & obj) : m_pBase(obj.m_pBase),m_dwOffset(obj.m_dwOffset) {}
~TreeNodeIter() {}
inline void Reset()
{
m_dwOffset = 0;
}
inline const TreeNodeIter<NodeType> & operator ++ ()
{
++m_dwOffset;
return *this;
}
inline TreeNodeIter<NodeType> operator ++ (int nDummy)
{
TreeNodeIter<NodeType> retValue(*this);
++m_dwOffset;
return retValue;
}
inline const TreeNodeIter<NodeType> & operator -- ()
{
--m_dwOffset;
return *this;
}
inline TreeNodeIter<NodeType> operator -- (int nDummy)
{
TreeNodeIter<NodeType> retValue(*this);
--m_dwOffset;
return retValue;
}
inline const NodeType & operator * () const
{
return *(m_pBase + m_dwOffset);
}
inline NodeType & operator * ()
{
return *(m_pBase + m_dwOffset);
}
inline const TreeNodeIter<NodeType> & operator = (const TreeNodeIter<NodeType> & udtIter)
{
if (this != &udtIter)
{
m_pBase = udtIter.m_pBase;
m_dwOffset = udtIter.m_dwOffset;
}
return *this;
}
inline const TreeNodeIter<NodeType> & operator = (const NodeType * pNode)
{
m_pBase = const_cast<NodeType *>(pNode);
m_dwOffset = 0;
return *this;
}
inline TreeNodeIter<NodeType> & operator += (unsigned long nValue)
{
m_dwOffset += nValue;
return *this;
}
inline TreeNodeIter<NodeType> & operator -= (unsigned long nValue)
{
m_dwOffset -= nValue;
return *this;
}
inline TreeNodeIter<NodeType> operator + (unsigned long nValue) const
{
TreeNodeIter<NodeType> udtRetValue(*this);
udtRetValue.m_dwOffset += nValue;
return udtRetValue;
}
inline TreeNodeIter<NodeType> operator - (unsigned long nValue) const
{
TreeNodeIter<NodeType> udtRetValue(*this);
udtRetValue.m_dwOffset -= nValue;
return udtRetValue;
}
private:
NodeType * m_pBase;
unsigned long m_dwOffset;
};
///////////////////////////////////////////////////
/// Note for tree nodes
/// You don't have to use the above node type (or as a base)
/// value tree node, however, you have to atleast
/// use the same naming conventions that
/// encapsulate the same functionality
///////////////////////////////////////////////////
template <typename NodeType> class Tree
{
public:
Tree();
virtual ~Tree();
/// Member Functions
bool Add(NodeType * pNode);
bool Add(NodeType * pNode,const IComparer<NodeType> * pComparer);
void Clear();
TreeNodeIter<NodeType> * GetIterator() const; /// NOTE: Should change this to return an object and not a pointer!
protected:
/// Member Variables
NodeType * m_pRootNode;
NodeType * m_pHighNode; /// Highest priority node
NodeType * m_pLowNode; /// Lowest priority node
unsigned long m_dwNodeCount; /// How many nodes are in the tree (base nodes, doesn't count equal nodes)
};
}
}
#include <poppack.h>
#include "Core.Vector.hpp"
#include "Core.List.hpp"
#include "Core.Tree.hpp"
#endif // CORE_COLLECTIONS_HPP_INCLUDED
-
Re: Abstract VS Encapsulation
Quote:
Originally Posted by
laserlight
Who won the first round? :)
I did but as nobody seemed willing to surrender to my genius I had to put in an entry also in the second round. :)
Quote:
As much as I like your definitions, that sounds like a bold claim. On what grounds do you say that they are "the definite definitions" with respect to OO programming instead of merely being your definitions?
It was a joke because unfortunately there are no definite definitions. Not even OO itself has a widely agreed upon definition.
To be bold, I think my definitions come very close to what many seasoned programmers could agree with. I've polished on them over a period of ten years since I went from C to Java and now to C++. I'm very proud of them so here they are again:
* Encapsulation is the idea of separating type and implementation from each other so they can be considered separately. The type is the outside view of an encapsulated entity. Hidden inside resides the implementation, a specific realization of the type.
* Abstraction is the process of defining a type. The type is used to declare variables which hold data and therefore a type is also called a data abstraction.
But, as always, I wellcome critisism of course.
-
Re: Abstract VS Encapsulation
There is a distinct REVERSAL in the terms....
When you encapsulate something your are taking something tangible and moving into something (and usually controlling access)
Quote:
Originally Posted by Websters Dictionary
Encapsulate - to enclose in or as if in a capsule
On the other hand when you create an abstraction, you are REMOVING the details (implementation) and retaining only the concepts.
Quote:
Originally Posted by Websters Dictionary
Abstraction- to consider apart from application to or association with a particular instance
Therefore ....
if you start with an abstraction and move into implementation then you can utilize encapsulation to hide the details.
if you start with an implementation (that may or may not utilize encapsulation) and remove the details, then you are left with an abstraction.
-
Re: Abstract VS Encapsulation
Quote:
Originally Posted by
TheCPUWizard
There is a distinct REVERSAL in the terms....
When you encapsulate something your are taking something tangible and moving into something (and usually controlling access)
On the other hand when you create an abstraction, you are REMOVING the details (implementation) and retaining only the concepts.
I don't think encapsulation and abstraction are related in that way. It's not like you can do encapsulation separated from abstraction, or abstraction separated from encapsulation.
Instead encapsulation requires abstraction. Abstraction is what creates the border around what's being encapsulated, namely minute details.
So this idea that there's a REVERSAL beween encapsulation and abstraction is wrong. Encapsulation requires abstraction.
Quote:
Therefore ....
if you start with an abstraction and move into implementation then you can utilize encapsulation to hide the details.
if you start with an implementation (that may or may not utilize encapsulation) and remove the details, then you are left with an abstraction.
In my world encapsulation is the goal. Abstraction is the means by which it's accomplished. It defines the divide between the type and the implementation.
-
Re: Abstract VS Encapsulation
Quote:
Originally Posted by
_uj
So this idea that there's a REVERSAL beween encapsulation and abstraction is wrong..
My reversal, I meant (and though I explained) the difference in Direction of the process (English language semantics). Very similar to the was tenses are used with verbs.
To encapsulate something requires having two distinct (real) entities, and placing one within the context of another.
To abstract something requires having at least one "real" thing, and distilling information out of it.
You could look at this sequence
1) Have a concept of an entity (this is an abstraction)
2) Create a concrete class which exposes ALL of the capabilities of this entity
3) Modify the concrete class to enclose some of the functionallty which can not be invked directly from extrernal source.
Abstration is going from 2 back to 1. Encapsulation is going from 2 to 3. Opposite directions in the process.
Quote:
Originally Posted by
_uj
Encapsulation requires abstraction.
There I have to disagree. Encapsulation does not require ANY abstraction what so ever. It is merely the act of placting something inside of something else. Consider three classes that are not directly related and are at the global scope. Put them into a namespace. You have not encapsulated them, but have NOT abstracted (removed) any aspect of the class.
-
Re: Abstract VS Encapsulation
Quote:
Originally Posted by _uj
I did but as nobody seemed willing to surrender to my genius I had to put in an entry also in the second round.
Nah, the first round ended in November 2007 (yes, advika resurrected the thread) without your participation :p
Quote:
Originally Posted by TheCPUWizard
Encapsulation does not require ANY abstraction what so ever. It is merely the act of placting something inside of something else. Consider three classes that are not directly related and are at the global scope. Put them into a namespace. You have not encapsulated them, but have NOT abstracted (removed) any aspect of the class.
Would I be correct to say that you included an extra not by accident? That is, you intended to write: "You have encapsulated them, but have NOT abstracted (removed) any aspect of the class."
I think that there is a miscommunication here due to two notions of encapsulation. One follows directly from the dictionary definition, and thus defines encapsulation as the placement of some entity in another entity. The other extends this with respect to object oriented programming, and it is this second notion of encapsulation that is inherently tied to abstraction, because it is about encapsulation of implementation, not encapsulation in a general sense.
Consider what Scott Meyers' wrote in his article on How Non-Member Functions Improve Encapsulation:
Quote:
Originally Posted by Scott Meyers
Encapsulation is a means, not an end. There's nothing inherently desirable about encapsulation. Encapsulation is useful only because it yields other things in our software that we care about. In particular, it yields flexibility and robustness. Consider this struct, whose implementation I think we'll all agree is unencapsulated:
Code:
struct Point {
int x, y;
};
The weakness of this struct is that it's not flexible in the face of change.
So, to make the struct flexible in the face of change, we remove the implementation details from the interface. This removal of details is abstraction. Yet Meyers talks about encapsulation instead of abstraction (by name), because the encapsulation of implementation is the removal of details.
-
Re: Abstract VS Encapsulation
Quote:
Originally Posted by
laserlight
Would I be correct to say that you included an extra not by accident? That is, you intended to write: "You have encapsulated them, but have NOT abstracted (removed) any aspect of the class."
:blush::blush::blush:
Quote:
I think that there is a miscommunication here due to two notions of encapsulation.Consider what Scott Meyers' wrote in his article on
How Non-Member Functions Improve Encapsulation:
So, to make the struct flexible in the face of change, we remove the implementation details from the interface. This removal of details is abstraction. Yet Meyers talks about encapsulation instead of abstraction (by name), because the encapsulation of implementation is the removal of details.
The implementations details still exist, they are what is encapsulated. What is left exposed is the abstraction.
Using the sample..
Code:
ORIGINAL:
class Point { public: int X; int Y };
Now the abstraction...
class Point
{
public :
int GetX(); void SetX(int);
int GetY(); void SetY(int);
}
Now the Encapsulation
private:
int m_X; // ++ implementation of GetX and SetX
int m_Y; // ++ implementation of GetY and SetY
If we look at this psuedo graphically:
Code:
InterfaceOnly <-------- Original ------> ImplementatioOnly
We have split the original. The creation (moving to the left) of the interface is abstraction. The creation (moving to the right) of the implementation is the encapsulation.
Left and Right are "reverse" directions spacially....
-
Re: Abstract VS Encapsulation
Quote:
Originally Posted by TheCPUWizard
The implementations details still exist, they are what is encapsulated. What is left exposed is the abstraction.
Yes, that is why I say "remove the implementation details from the interface".
Quote:
Originally Posted by TheCPUWizard
We have split the original. The creation (moving to the left) of the interface is abstraction. The creation (moving to the right) of the implementation is the encapsulation.
However, notice that they come as a pair: the encapsulation would be useless without the abstraction. In my opinion, this supports the notion that with respect to object oriented programming, abstraction and encapsulation are very much related. It also seems to me that people would then use "encapsulation" when they mean this abstraction + encapsulation pair.
Quote:
Originally Posted by TheCPUWizard
Left and Right are "reverse" directions spacially....
That seems more like a product of the illustration than something inherent in the concept. I feel that it would be more accurate to say that they complement each other rather than that one is the "reverse" of the other.
-
Re: Abstract VS Encapsulation
Quote:
Originally Posted by
laserlight
Yes, that is why I say "remove the implementation details from the interface".
However, notice that they come as a pair: the encapsulation would be useless without the abstraction. In my opinion, this supports the notion that with respect to object oriented programming, abstraction and encapsulation are very much related. It also seems to me that people would then use "encapsulation" when they mean this abstraction + encapsulation pair.
That seems more like a product of the illustration than something inherent in the concept. I feel that it would be more accurate to say that they complement each other rather than that one is the "reverse" of the other.
They definately MAY come as a pair, but none of the definitions of complement really apply.
Abstraction is the moving out of (extraction) of information, Encapsulation is the moving in. Going from Abstract to Concrete to Concrete with Encapsulation is a "one direction" process.
Looks like we will just have to agree to disagree on this semantic issue. :wave:
-
Re: Abstract VS Encapsulation
sounds like "abstraction helps encapsulation"
-
Re: Abstract VS Encapsulation
Quote:
Originally Posted by
thomus07
sounds like "abstraction helps encapsulation"
Not necessarily...
CODE1
Code:
class C
{
public:
int X;
};
void F(C &c)
{
++c.X;
}
CODE2
Code:
class C
{
public:
int X;
void F()
{
++X;
}
};
"Code2" encapsulates the functionallity of "F" within "C". But there is absolutely no abstraction.
CODE3
Code:
typedef void (*pfnFunc)(int &x);
void F(int &x) { ++x;}
pfnFunc pF = F;
pfnFunc is an an abstraction of any function which takes a integer by reference. There is absolutely no ecapsulation.
This is why my previous post said that MAY occur in tandem, but are not required to be related.
-
Re: Abstract VS Encapsulation
Your example makes sense.
Adhering to the topic, we concentrated our discussion relating encapsulation and abstraction. I think, if we separate the problem into encapsulation and then abstraction, we would be more clear.
If we understand each concepts separately and then if we relate to anything, we would be more clear.
I think most of us have an understanding of encapsulation.
Please can you make your input for abstraction, without relating to encapsulation (or any other concept.) :)
-
Re: Abstract VS Encapsulation
I wanted to agree to disagree and leave it there, but it looks like I cannot resist :D
Quote:
Originally Posted by TheCPUWizard
"Code2" encapsulates the functionallity of "F" within "C". But there is absolutely no abstraction.
There is, since C is an abstraction. If C is not an abstraction, then I would argue that there is no encapsulation of implementation, so in an object oriented sense, there is no encapsulation.
Quote:
Originally Posted by TheCPUWizard
This is why my previous post said that MAY occur in tandem, but are not required to be related.
I agree, if we are talking about abstraction and encapsulation as a general programming ideas, but I disagree if we are talking in terms of object oriented programming. Hence, in terms of object oriented programming, the term "complement" does apply since they are parts of a whole (the process of "moving" both "inwards" and "outwards", as you put it).
-
Re: Abstract VS Encapsulation
Quote:
Originally Posted by
TheCPUWizard
Not necessarily...
CODE1
Code:
class C
{
public:
int X;
};
void F(C &c)
{
++c.X;
}
CODE2
Code:
class C
{
public:
int X;
void F()
{
++X;
}
};
"Code2" encapsulates the functionallity of "F" within "C". But there is absolutely no abstraction.
There can be abstraction at different levels. In the above, you say that there is absolutely no abstraction - which is disagreeable to some extent. To me, the first one looks like an incomplete abstraction and the second one a complete one i.e. if the first example is in relation to a language of implementation where you do have full-featured OO support for example, in C++. But if you are dealing with a language of implementation where you do not have OO supporting features, then first one is the closest you can get to achieving abstraction, for example in C, where you do not have the notion of member functions forming part of the abstracted interface.
I feel comfortable with the distinction between abstraction and encapsulation that:
- abstraction is anything that's got to do with the user of the type, interface, functionality, whatever. It has nothing to do with how that type/interface/functionality/whatever is going to be implemented. You just ignore those details when doing abstraction. That's why I like the definition that Andrew Koenig uses for abstraction being 'Selective Ignorance'. We choose to ignore the details although they are important but not when doing abstraction. Those are the next step.
- encapsulation is the way to keep the details of those types, interfaces, functionality and other implementation details away from the user (user meaning user code here). This helps in flexibility/maintainability of design. In a way we can say, it has nothing to do with the usage of the abstraction or the user code itself but it ensures that the usage/user code doesn't try to make itself depend on the details that are prone to changes as the design evolves.
So, abstraction is at the level of functional use and encapsulation helps hide the details of how that 'use' is implemented.
Hence, I find myself in agreement with what Graham said and what laserlight said as well - encapsulation being complementary to abstraction. encapsulation helps abstraction - in fact it makes an abstraction beneficial and protects it in many ways. It is the hiding of the implementation detail that makes the abstraction successful in the way it has got to be.
The second class example, is a complete abstraction but is not very useful because it exposes the way the class is implemented - doesn't expose completely but does partially and that is bad. It keeps the data members exposed that can harm the system design and cause great coupling of the implementation detail (of which data members are also a part of) and the user code. Hence, that abstraction is not a complete success unless one encapsulates the detail (that in this particular example can be achieve by private keyword - hiding the data members). The details can change someday and break the rest of the code or atleast cause a huge ripple effect that is rarely desirable. Of course, it is not necessary to make the design a 'robust' one. :)
So, even if the above code (snippet 2) may be a 'complete' abstraction in itself - it may be a failure in ways if encapsulation doesn't 'protect' against that.
Quote:
Originally Posted by
TheCPUWizard
CODE3
Code:
typedef void (*pfnFunc)(int &x);
void F(int &x) { ++x;}
pfnFunc pF = F;
pfnFunc is an an abstraction of any function which takes a integer by reference. There is absolutely no ecapsulation.
Actually, I see both here! There is abstraction. How? The example abstracts the idea of a type that represents a function that takes so and so parameters and returns so and so results. That is what the user is to rely on. But there is encapsulation as well! How? The typedef! It hides away how the pfnFunc might be actually implemented behind the scenes. Well, note that the user can always see how the pfnFunc is implemented (as a typedef to a function pointer) but encapsulation doesn't protect against that. For example, even if a user can 'see' the private members in a class - and there can be ways to use those private details (reliable or unreliable - irrelevant) but that is not at all beneficial! As James Kanze says: "My recommendation in such cases would be to change the programmer, not the code" (source: C++ FAQ Lite).
How is that an encapsulation and how does it help? That is an encapsulation as it hides the details of how pfnFunc might be implemented. It helps in the way that tomorrow - one might opt to use a class to represent that function pointer and that shouldn't need the user code to change itself to adapt to that implementation details. Like this:
Today:
Code:
typedef void (*pfnFunc)(int &x);
void F(int &x) { ++x;}
pfnFunc pF = &F;
Tomorrow:
Code:
//can contain some state tomorrow
//can have enhanced log/call trace
//if not convinced just assume there can be a valid reason to provide a different implementation
struct pfnFunc_detail{
private:
typedef void (*pfnFunc_ptr)(int &x);
pfnFunc_ptr fptr;
public:
pfnFunc_detail(pfnFunc_ptr fptr_) : fptr(fptr_){}
void operator()(int& x) { fptr(x);}
};
typedef pfnFunc_detail pfnFunc;
void F(int &x) { ++x;}
int main()
{
pfnFunc pF = &F;
}
Here, pfnFunc_detail now can be a class underneath or just a typedef to a function pointer or that type. Another better example can be: a typedef to a StringCollection that might be a std::vector<std::string> today and std::vector<std::string, some_custom_allocator> someday or even std::deque<std::string> some other day. The user code is prevented as long as it follows the guidelines to usage of the StringVector (provided there is one, of course). That is how, I do suggest keeping a typedef for std::vector<bool>, in order to prevent user code from getting affected by much in case std::vector<bool> is changed tomorrow to mean something else (well, it means something else even today and hence the problem to which typedef is one of the solutions). The user code wouldn't need to adapt by much if I changed the typedef to say: std::deque<bool>. That's just one example where typedef helps encapsulate the detail of how my BoolVector is implemented. That is also one of the ways to achieve encapsulation in C as I stated in my earlier post.
Quote:
Originally Posted by
TheCPUWizard
This is why my previous post said that MAY occur in tandem, but are not required to be related.
They may occur in tandem. They are not required to be related. But in reality, encapsulation does complement abstraction and without it the abstraction can easily be a failure or not be achieved in the best possible way.
In the end, I do feel, everyone can have his own definition that they are comfortable with as long as the end product is the same and as long as there are sufficient reasoning behind those definitions. I do agree that I sometimes do use encapsulation to mean "abstraction + needed encapsulation". But some standardization or some guidelines certainly do help.