The object-oriented paradigm encourages encapsulation. Encapsulation is used to hide the mechanics of the object, allowing the actual implementation of the object to be hidden, so that we don't need to understand how the object works. All we need to understand is the interface that is provided for us.
You can think of this in the case of the 
Television class, where the 
functionality of the television is hidden from us, but we are provided with a remote control, or set of
controls for interacting with the television, providing a high level of abstraction.
So, as in Figure 1.4, “The 
Television interface example.” there is no requirement to understand how the signal is 
decoded from the aerial and converted into a picture to be displayed on the screen before you can use
the television.
There is a sub-set of functionality that the user is allowed to call, termed the interface. In the case of the television, this would be the functionality that we could use through the remote control or buttons on the front of the television.
The full implemenation of a class is the sum of the public interface plus the private implementation.
Encapsulation is the term used to describe the way that the interface is separated from the implementation. You can think of encapsulation as "data-hiding", allowing certain parts of an object to be visible, while other parts remain hidden. This has advantages for both the user and the programmer.
For the user (who could be another programmer):
The user need only understand the interface.
The user need not understand how the implementation works or was created.
For the programmer:
The programmer can change the implementation, but need not notify the user.
So, providing the programmer does not change the interface in any way, the user will be unaware of any changes, except maybe a minor change in the actual functionality of the application.
We can identify a level of 'hiding' of particular methods or states within a class using the
public, private and protected keywords:
public methods - describe the interface.
private methods - describe the implementation.
Figure 1.5, “The 
Television class example showing encapsulation.” shows encapsulation as it relates to the 
Television
class. According to UML notation private methods are denoted with a minus sign and public methods are denoted
with a plus sign. The private methods would be methods written that are part of the inner workings of the 
television, but need not be understood by the user. For example, the user would need to call 
the 
powerOn() method but the private 
displayPicture() method 
would also be called, but 
internally as required, not directly by the user. This method is therefore not added to the 
interface, but hidden internally in the implementation by using the private keyword.
If we have several descriptions with some commonality between these descriptions, we can group the descriptions and their commonality using inheritance to provide a compact representation of these descriptions. The object-oriented programming approach allows us to group the commonalities and create classes that can describe their differences from other classes.
Humans use this concept in categorising objects and descriptions. For example you may have 
answered the question - "What is a duck?", with "a bird that swims", or even more accurately, "a bird
that swims, with webbed feet, and a bill instead of a beak". So we could say that a Duck is a Bird that 
swims, so we could describe this as in Figure 1.6, “The 
Duck class showing inheritance.”. This figure illustrates the 
inheritance relationship between a 
Duck and a 
Bird. In effect we
can say that a 
Duck is a special type of 
Bird. 
For example: if were to be given an unstructured group of descriptions such as Car, Saloon, Estate, Van, Vehicle, Motorbike and Scooter, and asked to organise these descriptions by their differences. You might say that a Saloon car is a Car but has a long boot, whereas an Estate car is a car with a very large boot. Figure 1.7, “The grouped set of classes.” shows an example of how we may organise these descriptions using inheritance.
So we can describe this relationship as a child/parent relationship, where Figure 1.8, “The Base class and Derived class.”
illustrates the relationship between a base class and a derived class. A derived class inherits from a base
class, so in Figure 1.7, “The grouped set of classes.” the 
Car class is a child of the

Vehicle class, so 
Car inherits from 

Vehicle.
One way to determine that you have organised your classes correctly is to check them using the 
"IS-A" and "IS-A-PART-OF" relationship checks. It is easy 
to confuse objects within a class and children of classes when you first begin programming with an OOP
methodology. So, to check the previous relationship between 
Car and 

Vehicle, we can see this in Figure 1.9, “The IS-A/IS-A-PART-OF relationships and the 
Vehicle class.”.
The IS-A relationship describes the inheritance in the figure, where we can say, "A Car IS-A 
Vehicle" and "A SaloonCar IS-A Car", so all relationships are correct. The IS-A-PART-OF relationship 
describes the composition (or aggregation) of a class. So in the same figure (Figure 1.9, “The IS-A/IS-A-PART-OF relationships and the 
Vehicle class.”) we can
say "An Engine IS-A-PART-OF a Vehicle", or "An Engine, Colour and Wheels IS-A-PART-OF a Vehicle". This
is the case even though an Engine is also a class! where there could be many different descriptions of
an Engine - petrol, diesel, 1.4, 2.0, 16 valve etc.
So, using inheritance the programmer can:
Inherit a behaviour and add further specialised behaviour - for example a 
	
Car IS A 
Vehicle with the addition of four
	
Wheel objects, Seats etc.
Inherit a behaviour and replace it - for example the 
SaloonCar 
	class will inherit from 
Car and provide a new "boot" implementation.
Cut down on the amount of code that needs to be written and debugged - for example
	in this case only the differences are detailed, a 
SaloonCar is essentially
	identical to the 
Car, with only the differences requiring description.
When a class inherits from another class it inherits both the states and methods of that class, so
in the case of the 
Car class inheriting from the 
Vehicle
class the 
Car class inherits the methods of the 
Vehicle class, such
as 
engineStart(), 
gearChange(), 

lightsOn() etc. The 
Car class will also inherit the 
states of the 
Vehicle class, such as 
isEngineOn,

isLightsOn, 
numberWheels etc.
Polymorphism means "multiple forms". In OOP these multiple forms refer to multiple forms of the same method, where the exact same method name can be used in different classes, or the same method name can be used in the same class with slightly different paramaters. There are two forms of polymorphism, over-riding and over-loading.
As discussed, a derived class inherits its methods from the base class. It may be necessary to redefine an inherited method to provide specific behaviour for a derived class - and so alter the implementation. So, over-riding is the term used to describe the situation where the same method name is called on two different objects and each object responds differently.
Over-riding allows different kinds of objects that share a common behaviour to be used in code that only requires that common behaviour.
Consider the previous example of the 
Vehicle class diagram in 
Figure 1.7, “The grouped set of classes.”. In this case 
Car inherits from 

Vehicle and from this class 
Car there are further derived
classes 
SaloonCar and 
EstateCar. If a  

draw() method is added to the 
Car class, that is required to
draw a picture of a generic vehicle. This method will not adequately draw an estate car, or other 
child classes. Over-Riding allows us to write a specialised 
draw() method for the 

EstateCar class - There is no need to write a new 
draw()
method for the 
SaloonCar class as the 
Car class provides
a suitable enough 
draw() method. All we have to do is write a 
new 
draw() method in the 
EstateCar class with the 
exact same method name. So, Over-Riding allows:
A more straightforward API where we can call methods the same name, even thought these methods have slightly different functionality.
A better level of abstraction, in that the implementation mechanics remain hidden.
Over-Loading is the second form of polymorphism. The same method name can be used, but the number of parameters or the types of parameters can differ, allowing the correct method to be chosen by the compiler. For example:
add (int x, int y) add (String x, String y)
are two different methods that have the same name and the same number of parameters. However, when we pass
two 
String objects instead of two int variables then we expect different
functionality. When we add two int values we expect an int result - for example
6 + 7 = 13. However, if we passed two 
String objects we would expect a result of 
"6" + "7" = "67". In other words the strings should be concatenated.
The number of arguments can also determine which method should be run. For example:
channel() channel(int x)
will provide different functionality where the first method may simply display the current channel number, but the second method will set the channel number to the number passed.
An abstract class is a class that is incomplete, in that it describes a set of operations, but is missing the actual implementation of these operations. Abstract classes:
Cannot be instantiated.
So, can only be used through inheritance.
For example: In the 
Vehicle class example previously the 
draw()
method may be defined as abstract as it is not really possible to draw a generic vehicle. By doing this
we are forcing all derived classes to write a 
draw() method if they are 
to be instantiated.
As discussed previously, a class is like a set of plans from which you can create objects. In relation to this analogy, an abstract class is like a set of plans with some part of the plans missing. E.g. it could be a car with no engine - you would not be able to make complete car objects without the missing parts of the plan.
Figure 1.11, “The abstract 
draw() method in the 
Vehicle class.” illustrates this example. The 
draw() has been written
in all of the classes and has some functionality. The 
draw() in the 

Vehicle has been tagged as abstract and so this class cannot be instantiated - i.e.
we cannot create an object of the 
Vehicle class, as it is incomplete. In Figure 1.11, “The abstract 
draw() method in the 
Vehicle class.” 
the 
SaloonCar has no 
draw() method, but it does inherit a 

draw() method from the parent 
Car class. Therefore, it is possible to
create objects of 
SaloonCar.
 If we required we could also tag the 

draw() method as abstract in a derived class, for example we could also have
tagged the 
draw() as abstract in the 
Car class. This would 
mean that you could not create an object of the 
Car class and would pass on 
responsibility for implementing the 
draw() method to its children  - see 
Figure 1.12, “The abstract 
draw() method in the 
Vehicle and
    
Car classes.”
© 2006
  		Dr. Derek Molloy
  		(DCU).