Introduction to Object-Oriented Programming (OOP)

Submitted by coleen.yan@edd… on Mon, 04/22/2024 - 17:45

What is Object Orientated Programming (OOP)?

Object-oriented programming is the ‘modern’ alternative to procedural programming. It’s important to learn procedural programming first, so you understand what you are writing, but when you start to write programs that are a little more complex, such as mobile game apps, you will love the benefits of tidying up and reducing your code by using OOP. It follows one of the top principles of software development that you learned earlier in the course – DRY – Don’t repeat yourself.

In fact, in the video you’ll watch shortly, you’ll hear the following quote from Uncle Bob (career software engineer, author of ‘Clean Code’, instructor, and developer of many software development principles):

The best functions are those with no parameters!

OOP speeds things up, like building a house using some parts that are already put together for you, such as a bathroom sink unit that contains a tap, plug, plumbing, drawers, and cupboards already put together, rather than all separate pieces of wood and pipe and chrome that you put together one by one.

Advantages of OOP
  • Speeds up the coding process (less code to write)
  • Reduces code redundancy (unnecessary code/code repetition) (keeps program DRY)
  • Reduces errors from typing functions out so many times
  • Reduces mistakes by restricting how values can be accessed and manipulated (public/private).
Abstract Data Types (ADT)

OOP in C++ uses Classes and Objects. Classes are what we call an Abstract Data Type (ADT). This is a data type that is determined by the programmer. The programmer defines what values and functions can be used.

The user of the ADT does not need to know any implementation details. Just the expected inputs and output.

Procedural programming and OOP – what’s the difference?
Procedural programming Object-Orientated programming
Focuses on storing data in variables and writing separate functions Focuses on creating objects containing related data and functions
Languages used: Pascal, Fortrain, C Languages used: Java, C++, PHP, Ruby
No way to hide any data Data is more secure, using public/private
Top-down approach Bottom-up approach (inheritance)
Functions-based. Also variables, data structures, subroutines Object-based. Also classes, methods, properties, interfaces
Not based on real-world objects Based on real-world objects, with a state and behaviour
Code is written for one-time use Focus on reusable code, DRY

The four pillars of OOP

OOP is played out in four main ways:

  • Encapsulation
  • Abstraction
  • Inheritance
  • Polymorphism

What are these, you ask? Here’s a brief introduction, and then we’ll unpack each one in a bit more detail.

Encapsulation Grouping together functions (called methods) and data (called properties) that are directly related to each other into one "Object". A fridge object contains data and functions relating to fridges.
Abstraction Hiding some of the methods and properties in an object to reduce complexity for the user. Why provide a complicated remote, if all the users needs to interact with is a play button?
Inheritance When creating a new class (serviced) based on an existing class (base), base class features are inherited, but derived class can also have its own features. An example may include having a new car that has inherited features from a previous.
Polymorphism

Poly (many) morphism (forms).

We can write a method that will take different forms depending on the type of the object we are referencing. pourDrink() could produce one of five flavours here depending on which object its referencing.

For more information, watch mosh explain this in more detail in the following video:

Encapsulation

Grouping together functions (called methods) and data (called properties) that are directly related to each other into one "object". A fridge object contains data and functions relating to Fridges.

Some terms you should know: the functions are called the object’s methods or member functions, the data is called the object’s properties or attributes, and the data is stored in member variables, as these variables belong to the object.

Abstraction

Hiding some of the methods and properties in an object to reduce complexity for the user. Why provide a complicated remote, if all the user needs to interact with is a play button?

Abstraction is giving a general description of something while being non-specific. For example, a ‘triangle’ is abstract, it is a 3-sided polygon with no other specifics, but an ‘equilateral’ is not abstract, it is specific – a triangle with three sides of the same length.

C++ allows the programmer to restrict access to or visibility of some of the implementation details. For example, when creating a complex function, the user of that function doesn’t need to know all the calculations (functions) that happen to make it work, they just need to know what inputs are needed and what result to expect from the function, so the programmer might hide some of the functions and data.

This isn’t new to you in C++, think of all the functions you’ve already been using in your programming. You’ve just called them from the library without thinking about the calculations happening behind the scenes. Take the pow() function for example. It computes the power of a number. When the function iscalled, all the programmer needs to know is a. what inputs are required from me, and b. what result will I get?

Information hiding

A related principle, and part of abstraction, is called Information Hiding, where the goal is to only allow member functions to access and modify the object’s data. This is done by limiting access to some members of an object using these three access modifiers, public/private/protected.

But why would we do this? There are two reasons:

  1. Protection:
    Protects against accidental or deliberate data corruption.
  2. Need-to-know:
    As discussed earlier, users don’t need to know all the implementation details happening behind the scenes.
Inheritance

When creating a new class(Derived) based on an existing class (Base), Base class features are inherited, but Derived class can also have its own features. An example may include cars.

This is what is meant by ‘OOP is bottom-up’. When we create these car classes at the bottom of a chain, they are inheriting their features from the classes above.

Cars is the base class (think of a class a bit like a category), and the red car represents the BMW class which is called the derived class, as it has derived it’s features from the base class. The blue car represents the Porsche class, which is also a derived class.

The BMW class and the Porsche class have derived features from the Cars class, but they also have their own features (properties and methods) which are unique to their class. Imagine the features in a Porsche that wouldn’t be in a BMW and imagine all the features they have in common which can be set in the base class.

We’re not just talking about derived classes inheriting from base classes, but also objects inheriting features from their class.

Inheritance is where a lot of software reuse comes in, so many functions and attributes don’t have to be rewritten anymore, they can simply be inherited.

Polymorphism

Poly (many) morphism (forms). We can write a method that will take different forms depending on the type of the object we are referencing. pourDrink() could produce one of five flavours here depending on which object its referencing.

Poly means many and morphism comes from the word morphos which means forms. The example above talks about a method/function behaving differently depending on what object it is acting on. So in the soda fountain example above, the pourDrink() method will pour cola if applied to the cola object or it will pour raspberry fizz if applied to the raspberry object. Another example would be if you had a class called Animals with a method called makeNoise(), a derived Dog class or dog object would output "Woof!" if that function was run on it, however a derived Cat class or object would output "Meow!" if the same function was run on it.

There are two main types: compile-time polymorphism and runtime polymorphism.

A diagram depicting the types of polymorphism

Compile-time polymorphism has two types itself, which are operator overloading and function overloading. Whereas runtime polymorphism’s types are function overriding and virtual function.

For now, we will introduce operator overloading with a bit more detail. For more information on the rest of these, you could dig deeper by reading through Polymorphism in C++ and Types of Polymorphism (GreatLearning, 2021).

Operator overloading

Let’s look at the concept of Operator Overloading, it is a type of compiler-time polymorphism.

Operator overloading is a very interesting feature of C++. It allows you to ‘overload’ (or rewrite) the function of an operator. For example, you can define how you want + to behave when used on your class objects. This is used to perform functions on user-defined data types where the program would otherwise not know how to perform functions on them. This way you can operate on different kinds of data types with one operator.

To learn about how to use operator overloading, watch Bucky’s explanation and example in these two videos:

Part A:
Part B:

Sub Topics

Introduction to Classes and Objects

Classes are programmer-defined data types, a bit like a template or blueprint for their objects. It requires no memory itself. Objects are instances of Classes, and they hold the data, which will require memory.

The easiest way to understand objects is to look at real-world examples. Have a look at this real-world example of an object in OOP.

Example 1

In this example, the Class is Dog, which might even be a derived class from a base class called Animals. An object of this Dog class might be rufus. rufus contains member variables/attributes and member functions/methods. Member variables would be his height, weight, and how much food he eats, and his member functions are run(), play(), and eat(). Some of these functions will be derived from the base class, for example, eat() is something all animals do, so that would be a derived method.

A diagram depicting the object oriented programming
Example 2

Here is another example, this time the object is a square, which is a member of the class Square.

Objects are defined just like other variables:

 

Members are accessed using dot operators:

 

Its member variable would be the length of the sides, and its member functions would be setting the length of the sides and getting the length of the sides.

Square class diagram

Data

  • side: the length of square objects side

Functions

  • setSide(): function to set the length of the objects side
  • getSide(): function to get/return the length of the objects side

Note that these are two different types of member functions:

  • getSide() is an accessor/get/getter type, which accesses a member variable, but doesn’t change it.
  • setSide() is a mutator/set/setter type, which modifies a member variable.

Let's check out the following video, where Saldina gives an excellent coding example of creating a class and some objects in C++ OOP

Assess specifiers/modifiers

We previously alluded to access specifiers, and Saldina mentioned them in the video, they are:

  • private (+)
  • public (-)
  • protected (#)

Some things you need to know about access specifiers:

  • These determine how the member variables and member functions of a class can be accessed.
  • The only exception is that a class or function can be declared as a ‘friend’ of a certain class to allow access to that class’s members.
  • public, private, or protected… they don’t need to be in any order.
  • In class diagrams, which we will look at shortly, a class’ attributes and operations/functions are preceded with either a +, -, or a # to indicate the type of access allowed.

Have a look at the image below to bring clarity to the different specifiers.

Access specifiers of OOP
+ Public - Private (default) # Protected
Members can be accessed from inside and outside of the class Members can be accessed only from inside the class Members can be accessed only from inside the class or derived class
animalCLass ✓
animalClass ✓
animalClass ✓
            ^
dogClass ✓
 
*friend classes/functions ✓
*friend classes/functions ✓

Classes are also defined similarly to variables.

 

Notice the last semi-colon, after the closing curly bracket.

Example

In this example, we are declaring a class called Square using access specifiers

 

Now the blueprint is set for what an object of this class should contain, as a minimum.

Watch the second part of Saldina's explanation below and then attempt the activity that follows

Class and object activity

To complete this activity:

  • create a class for a combined class group of year 1 and year 2 (aged 5-7) school kids called juniors
  • set up 5 class objects with their full names (fake ones), ages, and school ‘year’
  • print out a list of the objects showing their names, ages, and years.

Your code might look something like this:

What are UML Class Diagrams?

Imagine you are writing a full program now. It’s quite possible that you will need to create many different classes that are all inter-related. For this, you will need to put together a diagram. We have talked about UML diagrams before, click on the link if you need to refresh your mind. Essentially, we are talking about using a universally accepted method to plan and document your object-oriented programs.

A software engineer writing a UML class diagram on paper

A UML class diagram is a structural type UML diagram which will display all the program’s classes including their member data (called attributes) and member functions (called operations), and the relationships between the classes.

Using this layout means it is easy to understand regardless of the programming language you will use.

Read UML class diagram concise tutorial (Develop Paper, 2021) to learn the ins and outs of creating UML class diagrams. Pay special attention to the relationships between classes, we will briefly discuss this shortly.

Classes activities

Use Visual Paradigm Online’s free class diagram builder to create a class to the given specifications. There are 5 practice activities for you to sink your teeth into.

Activity 1:Bank account

  • Create a class called BankAccount
  • The account can have an owner and a balance
  • Use deposit() and withdrawal() to change the balance
  • Need to be able to print the owner and the balance
  • Once the owner is set, it can’t be changed
  • Constructors can be used to initialise objects (you saw this in Saldina’s last video, however we will cover constructors in more detail later), list them at the start of the operators, with no return value.
Feedback

We hope you enjoyed your first play around with class diagram, the tools make it very easy for you, don't they?

Your class diagram should look something like this:

The output of the Bank account class diagram

Activity 2: Pizza

  • Create a class called Pizza
  • The pizza should have a name, cost, and diameter
  • It should also have a list of toppings, make this a vector of strings
  • We want to add one topping at a time to the vector
  • We want to print the cost of the pizza to the console
  • We want to print a list of all the toppings to the console
  • Create a constructor to initialise objects with the name, cost, and diameter.
Feedback

Your class diagram should look something like this:

The output of the Pizza class diagram

Activity 3: Circle

  • Create a class called Circle
  • Circle has a radius
  • We want to print the radius
  • We want to set the radius
  • We want to get the circumference of the Circle
  • We want to get the area of the Circle
  • Create two constructors:
    1. No arguments = create a Circle with radius of 1
    2. One argument = create a Circle with a radius provided by a parameter
Feedback

Your class diagram should look something like this:

The output of the Circle class diagram
Activity 4: Rectangle
  • Create a class called Rectangle
  • It has length measurement
  • It has width measurement
  • We want to print the length
  • We want to print the width
  • We want to assign the length
  • We want to assign the width
  • We want to find out the area of the Rectangle
  • Create two constructors:
    1. No arguments = create Rectangle with length of 2 and width of 1
    2. Two arguments = create Rectangle object with length and width from parameters
Feedback

Your class diagram should look something like:

The output of the Rectangle class diagram

Activity 5: Book

  • Create a class called Book
  • Has author, title, cost, and number of pages
  • We want to get the author name
  • We want to get the title
  • We want to get the cost
  • We want to get the number of pages
  • Create a constructor to initialise an object with: author, title, cost, and number of pages.
Feedback

Your class diagram should look something like this:

The output of the Book class diagram

Class relationships

A diagram depicting class relationships of UML diagrams

Association Shows that there is a relationship between these two classes. I.e.: a Cat and Mouse have an association because cats eat mice.
Dependency Used to show when one class (the client) uses, relies or depends on another class (the supplier). I.e.: a ShoppingCart class uses the Product class to add a product to the cart.
Inheritance One class is a "subclass" of another class, and takes on it's features along with its own. Also called generalisation (higher up you go, the more general)
Aggregation A type of association, where the sub/child class can exist without the parent class. I.e.: if a teacher is removed from a class, the students can/will still exist.
Realisation One class implements the details specified in an interface. I.e.: a stereo performs functions as determined by the interface.
Composition A type of association, where the sub/child class can't exist without the parent class. I.e.: if a house is destroyed by fire, so is its' kitchen.

When you are creating a class diagram you will need to link the various classes together to show how they relate to each other. We use different kinds of arrows to show different kinds of relationships. The image above shows the types of arrows with the relationship types, and on the right, you can see the same with a short description and example of the relationship.

Multiplicity

We will add details to the arrows to define the relationship even further, to indicate how many objects can be in this class in relation to one instance of a class. This is called multiplicity. Here are a few examples.

Expression Meaning Example
0...1 Zero or one Customer can bring their own bike on the bike ride or rent one. Maximum of one bike per person. So, customer’s bike class can be zero or one.
0...0 Must be zero Animal class should have no instances, the instances should come from the child classes such as lion or red panda. Can be written as 0 for short.
1...* One or more In a course, there is one teacher to one or more students.
1...1 Exactly one The car must have an engine, and can only have one engine, so the engine class should be 1…1. Can be written as 1 for short.
0...* Zero or more The courier truck can have zero or more packages.
m...m Exact number The puppy training camp can only go ahead if full and can only take 5 puppies, so, the trainee Puppy class should be 5…5. For this example, it can be written as 5 for short.
m...n Atleast and not more 0…1 means at least zero, and at most one.
5…10 means at least five, and at most ten.
A software training workshop needs to have at least 9 and no more than 12 participants: 9…12.

Watch Zach from Lucidchart explain relationships between classes and how we display these in our diagrams in his UML class diagram tutorial (Lucidchart, 2017)

Here are a few examples for you with More explanation.

Example 1- Association
An example of an association relationship
Example 2-Dependency

An object of the client class relies on/uses the supplier for a method. Exists if changes to one (supplier) may cause changes to the other (client), but not the other way around.

Class 1 depends on Class 2, as seen in this example, Order package uses Payment package.

An example of an dependency relationship
Example 3: Aggregation

Aggregation is a type of association relationship, it represents a “part of” a relationship. In this example a book is part of the library. The * shows that there can be many books associated with the library, and the 1 shows that there is only one library for each book.

Objects of the library and books have separate lifetimes.

An example of an aggregation relationship
Example 4: Composition

Composition is also a type of association relationship and represents a “part of” relationship. In composition, however, the parts are destroyed when the whole is destroyed. The car registration objects live and die with the car object, they cannot stand alone.

An example of a composition relationship
Example 5: Inheritance/Generalisation

The inheritance relationship is often called generalisation, because the higher you go up the diagram the more general the classes get.

Each class down the diagram is more specialised than the one above, it carries all the same methods and attributes, but also has it's own making it less general than the class above. An object of the Saint Bernard class is an ‘indirect’ instance of the mountain dog class.

Inheritance represents an “as is” relationship. For example, a Newfoundland is a mountain dog.

You can think of inheritance relationships as categories and sub-categories.

You can also have multiple inheritances, for example, a Labrador retriever is a cross between a Labrador and a Golden Retriever, it will inherit the features of both the Labrador and the Golden Retriever class.

An example of an inheritance or generalisation relatioship

UML Class diagram activities

Use Visual Paradigm Online’s free class diagram builder to create a UML class diagram to the given specifications. There are 3 practice activities for you to sink your teeth into.

Ensure you include the classes, relationships, and multiplicity.

Activity 1 – Hotel management system

For this activity, you will need to draw a UML class diagram that represents the following requirements for a hotel management system.

  • Hotel room bookings can be made by the receptionist (by phone) or by the guest (online).
  • Guests can order food items, which will be cooked by the chef and delivered by the hotel attendant.
  • Guests can make complaints to the manager.
  • The manager is responsible for ordering stock.
  • The receptionist needs to be able to print out the bill so the guest can pay it
Feedback

Have a look at this example of a simple hotel management system class diagram (Beriwal,2012)

Activity 2- Airport

For this activity, draw a UML class diagram that represents the following:

  • A country can have many airports.
  • A flight has an origin airport and a departure airport.
  • Planes are required to make flights.
  • Passengers go on flights with tickets and luggage.
Feedback

Have a look at this simple airport example (De Nicola, n.d.) and compare it to yours.

Activity 3 – Bank ATM

For this activity, draw a UML class diagram that represents the following:

  • Bank, ATM, ATM transaction, withdrawal, transfer.
  • Debit card, customer, account, savings account, checking account.
Feedback

Your diagram should look something like the ‘class diagram for ATM’ pictured part way down this article - UML Class diagram examples of common scenarios (EdrawMax, n.d)

A programmer teaching fellow employees about best practices

There is a saying that practice makes perfect. This is often used in relation to learning new skills. The more you practice, the better you will become at the skill. Go through the practice activities below.

Practice activity 1- removing special characters

By completing this activity, you will be practising the following C++ programming topics:

  1. Arrays
  2. Strings
  3. For Loop.

To complete this activity, you might need to do some of your own research to work out what is the best way to write a program in C++ that will remove all special characters in a string, leaving only letters from the alphabet.

In action, it should look something like this:

Enter a string: Th!sisn0t@v5r1g00d#x$mpl&
Output string: thsisntvrgdxmpl
Feedback

There are a few different ways to approach this, but whatever method you chose, you should have finished up with the ability to enter a string containing special characters, and then had the program output the string with only the alphabet characters, as illustrated below.

Practice activity 2- calculating time

By completing this activity, you will be practising the following C++ programming topics:

  1. Structure
  2. Function
  3. Pointer to structure.

To complete this activity, you will need to write a program in C++ that will take in two amounts of time and output the difference between them in hours, minutes, and seconds.

You are aiming to see something like this on your console:

Enter bigger time length. 
Enter hours, minutes, and seconds on their own lines: 72. 
52
20
Enter smaller time length. 
Enter hours, minutes, and seconds on their own lines: 72
42
20

TIME DIFFERENCE: 72:52:20 - 72:42:20 = 0:10:0

Practice activity 3- Guess the random number

For this activity, you will need to write a game in C++ that will allow the player to make multiple guesses until they find the correct random number that was generated by the program.

Just a few notes before you begin:

This is the sort of output you are aiming to create:

  • rand() does not produce a truly random number, but a pseudo-random value in a sequence of values ranging from 0 to RAND_MAX.
  • It is better to use srand() to set a random starting point in the sequence.
  • You initialise the random number generator using a seed. The most accepted way to do this is to use time as the seed, as the starting time of each game should be random. It will look like this: srand(time(0));
  • Your program will need to include the time header: #include<time.h>.
  • Now, the program will start generating numbers from a different point in the sequence each time it runs, depending on the time when it executes, making it appear less predictable than if you had simply used rand().

This is the sort of output you are aiming to create:


Guess the Random Number Game 
Enter a number between 1 and 100 : 75
Too high!

Enter a number between 1 and 100 : 35 
Too low! 

Enter a number between 1 and 100 : 55
Too low!

Enter a number between 1 and 100 : 65 
Correct! You got it in 4 guesses! 
Module Linking
Main Topic Image
A close up of a programmerr using laptop working from home with a backlit keyboard
Is Study Guide?
Off
Is Assessment Consultation?
Off