This is an intermediate conversion course for C++, suitable for second year computing students who may have learned Java or another language in first year.
2. Introduction
• One of the greatest tools available in object orientation for
the design of clean programs is encapsulation.
• Some writers make a distinction between encapsulation
and data hiding.
• I don’t find this to be a useful distinction, so we won’t be focusing
on it particularly.
• Just know that some of the things I talk about may have different
names if you read up on them elsewhere.
3. Encapsulation
• Encapsulation is the technique of storing data alongside
the methods that act upon that data.
• Sounds trivial, but it was a paradigm shift at the time.
• Objects provide a natural way of encapsulating data and
attributes.
• Objects also provide a way of managing access to those
data elements and attributes.
4. Encapsulation and the Impact of Change
• When used well, encapsulation greatly reduces the
impact of change in an application.
• By treating objects as atomic, it’s possible to swap them in
and out as possible.
• It’s also possible, if they are well designed, to refactor
them without any impact on the rest of the application.
5. Information Hiding
• One of the things that encapsulation permits is the
restriction of access to attributes and methods.
• This done through the use of visibility modifiers.
• There are three basic visibility modifiers common to Java
and C++
• Private
• Protected
• Public
6. Private
• Private indicates that visibility is restricted to the object in
which the item is defined.
• It is not available to external objects.
• It is not available to objects that extend the object.
• It is the most restrictive level of access.
• All attributes in a class should be private unless actively required to
be otherwise.
• It has the lowest impact of change.
• Refactoring can be limited to the class itself.
7. Protected
• Protected means that the class in which the item is
defined and any children of that class can get access.
• It’s not available to external objects.
• Any child that is specialised from, at some point, the class in which
the item is defined has access.
• Limits the impact of change to the defining class and
specialisations only.
• Refactoring can be limited to these classes.
8. Public
• The greatest level of visibility.
• Every object has access.
• Public methods that provide access to private attributes
are a good example of the utility of public methods.
• Accessor methods, as they are known.
• Greatest impact of change.
• You have to assume if something can be used, it is being used.
• Scope of refactoring becomes the entire program.
9. Why Hide Information?
• Simplify documentation.
• External documentation can focus on only relevant functions.
• Can ensure fidelity of access.
• If the only access to data is through methods you provide, you can
ensure consistency of access.
• Hides the implementation details from other objects.
• In large projects, a developer should not have to be aware of how a
class is structures.
• Simplifies code
• All access to the object through predefined interfaces.
10. Problems with Information Hiding
• They are conventions that have been adopted.
• You can’t guarantee they are being adhered to.
• Can lead to duplication of effort or over-engineering of
code solutions.
• Can lead to security leaks as people attempt to work
around restrictions.
• Especially a problem when working with pointers and object
references.
11. Encapsulation in C++
• So far, the concept is identical in C++ and Java.
• C++ offers an additional facility for defining visibility.
• The friend relationship.
• Friends have access to private attributes and methods
• We define specific classes as having friend access to our class.
12. Friends Will Be Friends
• We have two ways of defining a friend relationship.
• We can define a function as having friend access.
• We can define a class as having friend access.
• The first permits us to write our own implementation of a
method to access a private data attribute.
• Not a good idea.
• It breaks encapsulation.
• The second permits us to name a class as having
privileged access.
• Useful in certain limited circumstances.
• I’m told.
13. Friends Will Be Friends
using namespace std;
class Car {
friend class TestClass;
private:
float price;
string colour;
string *owners;
int max_size;
int current_size;
public:
Car();
Car (float, string = "bright green");
Car (float, string = "bright green", int = 20);
~Car();
void set_price (float p);
float query_price();
void set_colour (string c);
string query_colour();
string to_string();
int query_size();
int query_current_size();
void add_owner (string str);
string query_owner (int ind);
};
14. Friends Will Be Friends
class TestClass {
public:
void modify_price (Car *c, float f);
};
void TestClass::modify_price (Car *car, float x) {
car->price = x;
}
int main() {
ExtendedCar *myCar;
TestClass *bing
myCar = new ExtendedCar (100.0, "black", 10, 50.0);
bing = new TestClass();
bing->modify_price (myCar, 150.0);
cout << myCar->query_price () << endl;
return 1;
}
15. Friend Classes
• There are some caveats to using Friend relationships.
• The permission does not extend to derived classes.
• The permission is not reciprocated.
• If A is a friend of B, it doesn’t follow that B is a friend of A
• The permission is not transitive.
• Friends of friends are not friends.
16. Designing A Class
• A properly encapsulated class has the following traits.
• All data that belongs to the class is stored in the class.
• Or at least, represented directly in the class.
• All attributes are private.
• There’s almost never a good reason to make an attribute public.
• Hardly ever a good reason to make an attribute protected.
17. The Class Interface
• Classes have a defined interface.
• This is the set of public methods they expose.
• A properly encapsulated class has a coherent interface.
• It exposes only those methods that are of interest to external
classes.
• A properly encapsulated class has a clean divide between
its interface and its implementation.
18. Interfaces
• The easiest way to think of an interface is with a metaphor.
• Imagine your car’s engine.
• You don’t directly interact with the engine.
• You have an interface to that car engine that is defined by:
• Gears
• Pedals
• Ignition
• Likewise with the car wheels.
• Your steering wheel is the interface to your wheels.
• As long as the interface remains consistent…
• It doesn’t matter what engine is in the car.
• Change the interface, and you can no longer drive the car the same way.
19. Interface and Implementation
• Within a properly encapsulated class, it does not matter to
external developers how a class is implemented.
• I know what goes in
• I know what comes out
• The interface to a class can remain constant even while
the entirety of the class is rewritten.
• Not an uncommon act in development.
20. Interface and Implementation
• It’s important to design a clean an effective interface.
• It’s safe to change encapsulated implementation.
• It’s usually not safe to change a public interface.
• You are committed to the code that you expose publicly.
• When new versions of Java deprecate existing functionality, they
never just switch it off.
21. Summary
• Encapsulation is the third of the three key principles of
object orientation.
• It is properly broken up into two separate concepts.
• Encapsulation and Information Hiding
• Visibility modifiers exist to restrict access to objects.
• C++ (not Java) makes available a special relationship
known as a friend relationship.