TCP1201 OOPDS
Coursework 60%, Final exam 40%
Coursework 60%– 2 Written Quizzes – (10% + 15%) each
• Q1: 6 Aug (Thurs) *• Q2: 9 Sept (Thurs) *
– 2 Assignments – 10% each• AS1: Due - beginning of Week 7 *• AS2: Due - beginning of Week 123 *
– 1 Lab Test – 15%• 27 Aug (Thurs) *
* Tentative
1
TCP1201 OOPDS
Min attendance rate: 80% Min coursework mark for supp. exam
entitlement: 50% (Just working hard for final exam may not be sufficient)
Last week to withdraw: Week 7 (check your coursework mark by Week 7)
Compiler: CodeBlocks 13.12 (latest) Link: http://www.codeblocks.org/
2
References
REFERENCE BOOKS Deitel, H. M., & Deitel. P. J. (2012). C++ How to Program (8th
ed.). Pentice Hall Carrano, F. M. and Henry, T. (2012). Data Abstraction &
Problem Solving with C++. Pentice Hall
WEB REFERENCES 1. http://www.cplusplus.com/ 2. http://www.cppreference.com 3. http://www.learncpp.com/ 3
TEXTBOOK: Savitch. W. (2014). Problem Solving
with C++ (9th ed.). Addison-Wesley. Childs, J. (2008) C++ Classes and
Data Structures. Prentice Hall
Introduction to Object-OrientedProgramming
TCP1201 OOPDS 4
Lecture 1
5
To understand object & class To understand abstraction in C++ To understand encapsulation in C++ To categorize similar objects To categorize objects by Composition To construct UML Class Diagram To differentiate between Procedural
Programming and Object-Oriented Programming
Learning Objectives
What is an “object”?
An object is a computer representation of real-world person, place, event or anything in the problem that we are solving.
7
What is an “object”? An object consists of:
– attributes/data/states/fields/variables (typically noun), e.g. name, date, balance, size, mark, etc.
– behaviors/procedures/methods/operations/functions (typically verb), e.g. eat, drive, set, get, push, etc.
We refer to a group of similar objects with the same attributes and behaviors as a class.
Object and ClassClass: Student.Attributes: name, student_ID.Behavior/method: do_homework().Objects of Student class: steve, victor.
Object and Class
Steve and victor share the same attributes (name & student_id), but each object has its own value for the attributes.
10
Object and Class We refer to a group of similar objects with
the same attributes and behaviors as a class.
Thus, we can define a class as:– “a set of objects comprised of the
same attributes and behaviors”. Thus, we can define object as “a
particular instance of a class”.
11
Object-Oriented Programming
The idea is to design a program to solve a problem by combining both the data and procedures (member functions) that operate on that data into a singe unit called object.
Popular OOP languages: C++, Java, C#, VB, etc.
C++ in TCP1201 focuses on OOP.
Object1 Object3
Object2
12
Steps to Use OOP
3. Determine how the objects interact with one another (messaging).
Data
Member Function
Data
Member Function
Data
Member Function
Messages
2. Identify the data/attributes and operations/methods in each object.
1. Identify the objects
13
4 Principles of OOP
1. Abstraction – identify the properties that are important to the user in the problem, and create representations that are similar to its original meaning.
2. Encapsulation – combine data and its operations in a single unit, and hide the implementation from user.
3. Inheritance – create new classes from existing classes (Lecture 3).
4. Polymorphism – use the same expression to denote different operations (Lecture 4).
14
OOP Principle – Abstraction
Abstraction is the process of identifying important logical properties (object, attributes, methods) that simplifies the modeling and working of the problem.
If you are designing a mobile phone, example properties that are important to the user are the screen, keypad, UI, cover, etc., but not the internal working of the processor, how the screen is actually rendered, etc.
15
OOP in Practice – Abstraction
Assume that we are developing simple system to keep track of subjects registered by student. It won't be difficult to identify the following Student class, its attributes and behaviors/methods.
Attributesidsubjects
Methodsshow_subjectsregister_subjectwithdraw_subject
ClassStudent
16
OOP in Practice – Abstraction
Based on what we collected and consider appropriate data type, the following class definition can be declared:
class Student { int id; vector<string> subjects; void show_subjects(); void register_subject(); void withdraw_subject();};
class
17
OOP in Practice – Abstraction
Based on what we collected and consider appropriate data type, the following class definition can be declared:
class Student { int id; vector<string> subjects; void show_subjects(); void register_subject(); void withdraw_subject();};
attributes
18
OOP in Practice – Abstraction
Based on what we collected and consider appropriate data type, the following class definition can be declared:
class Student { int id; vector<string> subjects; void show_subjects(); void register_subject(); void withdraw_subject();};
methods
19
OOP Principle – Encapsulation
Encapsulation is the idea that the internal workings of an object can be hidden from the outside world.
Encapsulation is performed in 2 ways:1. We encapsulate how attributes are
accessed via access privileges (private, public, protected, friend).
2. We encapsulate how methods are implemented by separating interface and implementation into different files.
20
Access Privileges in C++ Access privileges allow us to restrict the
access to an object’s members. 4 types of access privileges in C++:1. private2. public3. protected (Lecture 3 Inheritance)4. friend (Lecture 5 Operator Overloading)
private and public Access Privileges
private members Not accessible from
anywhere except for the object itself.
We generally declare attributes as private.
By default, all members of a C++ class are declared as private if unspecified.
public members Accessible from
anywhere including outside the class.
We generally declare methods as public.
By default, all members of a C++ struct are declared as public if unspecified.
21
22
OOP Principle – Encapsulation
To maintain data integrity, attribute is usually set hidden/private inside a class to prevent direct modification from outside the class.
To access or modify an object‘s attribute from outside the class, we provide public get or set methods.– Get method – a method that returns the
value of an attribute but does not modify it.
– Set method – a method that modifies the value of an attribute.
23
OOP in Practice – Encapsulation
Since all our methods are meant to be used from outside the class, we should declare them as public.
class Student { // private by default int id; vector<string> subjects; public: // public from now on int getId(); // get method for id void setId (int id); // set method for id void show_subjects(); void register_subject(); void withdraw_subject();};
private
public
24
OOP in Practice – Encapsulation
Since all our methods are meant to be used from outside the class, we should declare them as public.
class Student { // private by default int id; vector<string> subjects; public: // public from now on int getId(); // get method for id void setId (int id); // set method for id void show_subjects(); void register_subject(); void withdraw_subject();};
private attribute
public method to access the
private attribute
25
Placing Implementation There are 2 ways to place the
implementation (method body) in C++.
class Student { int id; ... int getId(); //prototype void setId (int id); //prototype ...}; // End of class
int Student::getId() { return id;}void Student::setId (int id) { this->id = id;}
class Student { int id; ... int getId() { return id; }
void setId (int id) { this->id = id; } ...}; // End of class
Inside of class declarationOutside of class declaration
26
Placing Implementation Outside of Class Declaration "::" is a scope resolution operator. "Student::" indicates that the function is a
method of Student class, not a global function.class Student { int id; ... int getId(); //prototype void setId (int id); //prototype ...}; // End of class
int Student::getId() { return id;}void Student::setId (int id) { this->id = id;}
27
The this Pointer
We use this pointer to refer to a member of a class.
class Student { int id; ... void setId (int id); //prototype ...}; // End of class...void Student::setId (int id) { this->id = id;}
id here is function parameter, not attribute
id here is attribute
28
The this Pointer We use this pointer to refer to a member of a
class.
class Student { int id; ... void setId (int id); //prototype ...}; // End of class...void Student::setId (int id) { id = id; // Wrong, "parameter = parameter". // Attribute id is not updated. this->id = id; // Correct, "attribute = parameter". Student::id = id; // Correct, "attribute = parameter".}
29
Maintaining Data Integrity with Encapsulation
By declaring attributes as private and providing public set methods, we can prevent erroneous data being entered into the object.
...// Ensure id entered is within range.void Student::setId (int id) { if (id < 1000000000 || id > 9999999999) { cout << "Error: Id out of range.\n"; this->id = 0; } else this->id = id;}
30
Placing Interface and Implementation in Separate
Files To bring encapsulation to the next level, we
separate the interfaces and its implementations into different files.
For every class:– Place its interface in a .hpp file – called header file, e.g.
Student.hpp.– Place its implementation in a .cpp file – called source
file, e.g. Student.cpp.– In every cpp that needs to refer to the class, "#include"
the hpp.
31
HPP Header File The use of #ifndef, #define & #endif is to
prevent multiple inclusion.// Student.hpp header file#ifndef STUDENT_HPP // Prevent multiple inclusion.#define STUDENT_HPP#include <iostream>#include <string>using namespace std;
class Student { int id; vector<string> subjects; public: int getId(); void setId (int id); void show_subjects(); void register_subject(); void withdraw_subject();}; // End of class#endif
interface
32
CPP Source File
Every cpp source file that needs to refer to the class should "#include" the hpp.
// Student.cpp source file#include "Student.hpp" // Use "", not <>.
int Student::getId() { return id; }void Student::setId (int id) { this->id = id; }void Student::show_subjects() { ... }void Student::register_subject() { ... }void Student::withdraw_subject() { ... }
// main.cpp source file#include "Student.hpp" // Use "", not <>.
int main() { Student s; s.register_subject(); ...}
Implementations
33
Why Encapsulation?1. To maintain data integrity
– By limiting direct access to attributes, we prevent class users from providing invalid data to the object.
2. To reduce the need for class users to worry about the implementation– By separating the interface from the
implementation (shorter class declaration), class users can focus on using the class instead of being bothered by the implementation of the class.
3. To improve program maintenance– Separating the interface from the
implementation enables us to change the implementation without the class users ever being aware (provided that the interface remains the same).
34
Categorizing Objects There might be many objects. 2 common ways to categorize objects are:1. Categorize similar objects that have the
same attributes and behaviors, e.g. the student example.– We have covered this one up until now.
2. Categorize objects by composition, that is when an attribute of a class is a class by itself, e.g. a faculty has many students.
35
Categorizing by Composition When categorizing objects by composition, an
attribute of a class is a class by itself. Is also referred to as a “has-a” relationship. Example 1: A faculty has many students (both
faculty and student are classes). Example 2: Typical corporate organization:
– 3 classes can be identified: Dept, Staff, Data.– A Dept has Staff and Data.
Personnel Data
PersonnelStaff
Finance Data
Finance Staff
Sales Data
Sales Staff
Sales Dept. Finance Dept.
Personnel Dept.
Messages
36
Categorizing by Composition Sample code for the composition involving faculty
and student.
class Student { // Student is a class. ...}; // End of class
class Faculty { // Faculty is a class. string name; vector<Student> students1; // Composition, attribute is // a class by itself. // vector<Student*> students2; // Also composition. // Student students3[10]; // Also composition. // Student* students3; // Also composition. ...};
37
UML Class Diagram UML is a formal notation to describe
models (representations of things/objects) in sofware development.
Class Diagram is one type of many diagrams in UML.
Class Diagram contains 2 elements:– Classes represent objects with common
attributes, operations, and associations.– Associations represent relationships that
relate two or more classes.
Student
38
Class Diagram
Must have 3 sections. Class name is placed at the top
section. Attributes are placed at the
middle section. Behaviors are placed at the
bottom section. '-' denotes private access
privilege. '+' denotes public access
privilege. '[*]' denotes "many" (array,
vector).
-id:int-subjects:string[*]
+getId():int+setId(id:int):void+show_subjects():void+register_subject():void+withdraw_subject():void
39
Class Diagram
Associations shows the relationship between instances of classes, e.g. a faculty has one or more students, a student belongs to exactly one faculty only.
Faculty
-name:string-students:Student[*]
+intake()
Association
1 1..n
'n' means many
Student
-id: int-subjects:string[*]
+getId():int+setId(id:int):void+show_subjects():void+register_subject():void+withdraw_subject():void
Composition
40
Revisiting Procedural Programming
C++ in TCP1101 is taught as a procedural programming language.
In procedural programming, the idea is to design a program to solve a problem by concentrating on the procedures first and data second. This approach is known as top-down design.
Procedures and data are 2 separate units that relate primarily via function parameter.
Main ProgramData
Function1 Function2 Function3
41
Problems with Procedural Programming
Unrestricted access to global data and procedures.
Poor modeling of the real world (data and procedures are separated). Not the way that humans
naturally think about a situation. Poor code reusability.
struct Student { int id; vector<string> subjects;};
void register_subject (Student& a) { ... }
void withdraw_subject (Student& s){ ... }
int main() { Student s; register_subject (s); withdraw_subject (s);}
Why Object-Oriented Programming? Solve the problems of procedural programming. Restrict access to data and procedures (via
encapsulation). Better modeling of real world objects (via
abstraction).– Data and procedures are combined in a single unit.– Easier to understand, correct, and modify.
Better code reusability – existing objects can be reused to create new objects via inheritance (Lecture 3).
More useful for development of large and complex systems.
43
Converting Procedural Program to OOP
1. Identify the variables and the global functions that use the variables as parameters, create a class and include the variables and the global functions as class members.
2. Make all attributes private.3. For methods that use the class as
parameter(s), remove ONE such parameter. Then update the method body to refer to the member instead of the removed parameter.
44
// Procedural version#include <iostream>#include <string>#include <cmath>using namespace std;struct Point { int x, y; //public by default};
Point readPoint();void printPoint (Point);double distPoint (Point, Point);
int main() { Point p1 = readPoint(); cout << "p1 = "; printPoint (p1); cout << endl; Point p2 = readPoint(); cout << "p2 = "; printPoint (p2); cout << endl << endl; double d = distPoint (p1, p2); cout << "Distance p1 to p2 = " << d << endl;}
Point readPoint() { Point p; cout << "Enter point x y : "; cin >> p.x >> p.y; return p;}
void printPoint (Point p) { cout << "(x = " << p.x << ", y = "<< p.y << ")" << endl;}
double distPoint (Point p, Point q) { double dx = p.x - q.x; double dy = p.y - q.y; double dsquared = dx*dx + dy*dy; return sqrt (dsquared);}
45
// Procedural version#include <iostream>#include <string>#include <cmath>using namespace std;struct Point { int x, y; //public by default};
Point readPoint();void printPoint (Point);double distPoint (Point, Point);
int main() { Point p1 = readPoint(); cout << "p1 = "; printPoint (p1); cout << endl; Point p2 = readPoint(); cout << "p2 = "; printPoint (p2); cout << endl << endl; double d = distPoint (p1, p2); cout << "Distance p1 to p2 = " << d << endl;}
Point readPoint() { Point p; cout << "Enter point x y : "; cin >> p.x >> p.y; return p;}
void printPoint (Point p) { cout << "(x = " << p.x << ", y = "<< p.y << ")" << endl;}
double distPoint (Point p, Point q) { double dx = p.x - q.x; double dy = p.y - q.y; double dsquared = dx*dx + dy*dy; return sqrt (dsquared);}
46
// Procedural version#include <iostream>#include <string>#include <cmath>using namespace std;struct Point { int x, y; //public by default};
Point readPoint();void printPoint (Point);double distPoint (Point, Point);
int main() { Point p1 = readPoint(); cout << "p1 = "; printPoint (p1); cout << endl; Point p2 = readPoint(); cout << "p2 = "; printPoint (p2); cout << endl << endl; double d = distPoint (p1, p2); cout << "Distance p1 to p2 = " << d << endl;}
Point readPoint() { Point p; cout << "Enter point x y : "; cin >> p.x >> p.y; return p;}
void printPoint (Point p) { cout << "(x = " << p.x << ", y = "<< p.y << ")" << endl;}
double distPoint (Point p, Point q) { double dx = p.x - q.x; double dy = p.y - q.y; double dsquared = dx*dx + dy*dy; return sqrt (dsquared);}
47
// Procedural version#include <iostream>#include <string>#include <cmath>using namespace std;struct Point { int x, y; //public by default};
Point readPoint();void printPoint (Point);double distPoint (Point, Point);
int main() { Point p1 = readPoint(); cout << "p1 = "; printPoint (p1); cout << endl; Point p2 = readPoint(); cout << "p2 = "; printPoint (p2); cout << endl << endl; double d = distPoint (p1, p2); cout << "Distance p1 to p2 = " << d << endl;}
Point readPoint() { Point p; cout << "Enter point x y : "; cin >> p.x >> p.y; return p;}
void printPoint (Point p) { cout << "(x = " << p.x << ", y = "<< p.y << ")" << endl;}
double distPoint (Point p, Point q) { double dx = p.x - q.x; double dy = p.y - q.y; double dsquared = dx*dx + dy*dy; return sqrt (dsquared);}
48
// Procedural version#include <iostream>#include <string>#include <cmath>using namespace std;struct Point { int x, y; //public by default};
Point readPoint();void printPoint (Point);double distPoint (Point, Point);
int main() { Point p1 = readPoint(); cout << "p1 = "; printPoint (p1); cout << endl; Point p2 = readPoint(); cout << "p2 = "; printPoint (p2); cout << endl << endl; double d = distPoint (p1, p2); cout << "Distance p1 to p2 = " << d << endl;}
Point readPoint() { Point p; cout << "Enter point x y : "; cin >> p.x >> p.y; return p;}
void printPoint (Point p) { cout << "(x = " << p.x << ", y = "<< p.y << ")" << endl;}
double distPoint (Point p, Point q) { double dx = p.x - q.x; double dy = p.y - q.y; double dsquared = dx*dx + dy*dy; return sqrt (dsquared);}
49
// OOP version#include <iostream>#include <string>#include <cmath>using namespace std;
class Point { int x, y; // private by default public: void readPoint(); void printPoint(); double distPoint (Point q);};
void Point::readPoint() { cout << "Enter point x y : "; cin >> x >> y;}void Point::printPoint() { cout << "(x = " << x << ", y = " << y << ")" << endl; }
double Point::distPoint (Point q) { double dx = x - q.x; double dy = y - q.y; double dsquared = dx*dx + dy*dy; return sqrt(dsquared);}
int main() { Point p1, p2;
p1.readPoint(); cout << "p1 = "; p1.printPoint(); cout << endl; p2.readPoint(); cout << "p2 = "; p2.printPoint(); cout << endl; double d = p1.distPoint (p2); cout << "Distance p1 to p2 = " << d << endl;}
50
// OOP version#include <iostream>#include <string>#include <cmath>using namespace std;
class Point { int x, y; // private by default public: void readPoint(); void printPoint(); double distPoint (Point q);};
void Point::readPoint() { cout << "Enter point x y : "; cin >> x >> y;}void Point::printPoint() { cout << "(x = " << x << ", y = " << y << ")" << endl; }
double Point::distPoint (Point q) { double dx = x - q.x; double dy = y - q.y; double dsquared = dx*dx + dy*dy; return sqrt(dsquared);}
int main() { Point p1, p2;
p1.readPoint(); cout << "p1 = "; p1.printPoint(); cout << endl; p2.readPoint(); cout << "p2 = "; p2.printPoint(); cout << endl; double d = p1.distPoint (p2); cout << "Distance p1 to p2 = " << d << endl;}
51
// OOP version#include <iostream>#include <string>#include <cmath>using namespace std;
class Point { int x, y; // private by default public: void readPoint(); void printPoint(); double distPoint (Point q);};
void Point::readPoint() { cout << "Enter point x y : "; cin >> x >> y;}void Point::printPoint() { cout << "(x = " << x << ", y = " << y << ")" << endl; }
double Point::distPoint (Point q) { double dx = x - q.x; double dy = y - q.y; double dsquared = dx*dx + dy*dy; return sqrt(dsquared);}
int main() { Point p1, p2;
p1.readPoint(); cout << "p1 = "; p1.printPoint(); cout << endl; p2.readPoint(); cout << "p2 = "; p2.printPoint(); cout << endl; double d = p1.distPoint (p2); cout << "Distance p1 to p2 = " << d << endl;}
52
// OOP version#include <iostream>#include <string>#include <cmath>using namespace std;
class Point { int x, y; // private by default public: void readPoint(); void printPoint(); double distPoint (Point q);};
void Point::readPoint() { cout << "Enter point x y : "; cin >> x >> y;}void Point::printPoint() { cout << "(x = " << x << ", y = " << y << ")" << endl; }
double Point::distPoint (Point q) { double dx = x - q.x; double dy = y - q.y; double dsquared = dx*dx + dy*dy; return sqrt(dsquared);}
int main() { Point p1, p2;
p1.readPoint(); cout << "p1 = "; p1.printPoint(); cout << endl; p2.readPoint(); cout << "p2 = "; p2.printPoint(); cout << endl; double d = p1.distPoint (p2); cout << "Distance p1 to p2 = " << d << endl;}