Hello everyone,
Please can somebody explain to me the main differences between the principles of encapsulation and abstraction in objected-oriented programming (if possible with examples).
Thanks in advance.
Hello everyone,
Please can somebody explain to me the main differences between the principles of encapsulation and abstraction in objected-oriented programming (if possible with examples).
Thanks in advance.
Encapsulation means that object's internal state (data) can be modified only by its public methods (public interface):
class Encapsulated {
private int data;
public int getData() { return data; }
public void setData(int d) { data = d; }
}
Abstraction means that you can abstract from concrete implementations, for example:
abstract class Container {
int getSize();
}
class LinkedList extends Container {
int getSize() { /* return the size */ }
}
class Vector extends Container {
int getSize() { /* ... */ }
}
If you will be using the Container abstract class in all your code instead of Vector or LinkedList, you will be able to switch the concrete implementation of Container (Vector/LinkedList in this case) without changing any of your code, thus abstracting yourself from the implementation.
The two concepts are distinct, but closely related and are often found together.
Abstraction is hiding of non-essential details, usually termed implementation details. For example, to read data from a stream, most environments have the concept of an InputStream
. It provides a ReadBytes() method to fetch more bytes from the stream. How it does this is abstracted away - it could be reading from a file, using the OS file APIs, or reading from a socket, from SSH or anything else that can be presented as a stream of bytes. The InputStream class is said to be an abstraction.
Each implementation of InputStream codes how the bytes are read. For example, a FileInputStream reads bytes from a file, and maintains the current offset into the file as a private data member. Code external to the class does not have free access to read or write this variable directly - doing so might lead to incorrect results, such as part of the stream being skipped, or re-read. This is especially important in multi-threaded scenarios, when changes to the variable needs to be carefully controlled. Instead of giving unfettered access, the class uses the offset
internally (by declaring it private
), and gives external code only indirect access, such as via a method GetCurrentOffset()
, and methods Seek(int offset)
. The offset variable is then encapsulated by the FileInputStream class.
Sample:
// NO ABSTRACTION, NO ENCAPSULATION
const int catLegs = 4;
const int spiderLegs = 8;
Leg[] catLegs;
Leg[] spiderLegs;
void MakeCatRun(Distance b) { for (int i=0; i<catLegs; ++i) catLegs[i] += b; }
void MakeSpiderRun(Distance b) { for (int i=0; i<spiderLegs; ++i) spiderLegs[i] += b; }
Encapsulation:
// ENCAPSULATION
class Cat
{
Leg[] legs;
int nLegs;
public void Run(Distance b) { for (int i=0; i < nLegs; ++i) leg[i] += b; }
}
class Spider
{
Leg[] legs;
int nLegs;
public void Run(Distance b) { for (int i=0; i < nLegs; ++i) leg[i] += b; }
}
Abstraction:
// ABSTRACTION
class LivingBeing
{
Leg[] legs;
int nLegs;
public void Run(Distance b) { for (int i=0; i < nLegs; ++i) leg[i] += b; }
}
class Cat: LivingBeing { }
class Spider: LivingBeing { }