CIE 202 - Unit 02 - Objects and Classes
CIE 202 - Unit 02 - Objects and Classes
these slides
Unit 2 Liang, Y.
Daniel. Introductio
n to Programming
Classes
Starting out with
C++
C++: from control
structures through
objects. Pearson,
2012.
Tamer A Ali
1
Functional Programing and
Object-Oriented
Programing
• Functional programming focuses on the
process/actions that occur in a program
2
Limitations of Procedural
Programming
• If the data structures change, many functions must
also be changed
3
Object-Oriented
Programming
• Everything is an object.
• Objects can
• communicate by messages
• have their own memory
• Every object is an instance of a class
• The class holds the shared behavior for its
instances.
4
Classes and Objects
• A Class is like a blueprint and objects are like houses
built from the blueprint
5
Functional Programing and
Object-Oriented
Programing
Functional Object-Oriented
Programing Programing
When you have a fixed When you have a fixed
set of things set of operations on
things
as your code evolves as your code evolves
you add new you add new things.
operations on existing
things.
6
Object-Oriented
Programming
OOP enables you to develop large-scale software
effectively
An object:
• Represents an entity in the real world that can be
distinctly identified.
• A student, a desk, a circle, a button, a loan, …
• Has a unique identity, state, and behaviors.
7
Object-Oriented
Programming
Terminology
• Attributes / data fields / properties: members
variables of a class
8
More on Objects
• data hiding: restricting access to certain members
of an object
9
Class Example
class Circle
{
private:
double radius;
⋮
public:
⋮
void setRadius(double);
double getRadius() const;
double getArea() const;
10
}; 10
Objects
A construct that defines objects
of the same type.
12
Classes Example
class Circle
{
public:
// The radius of this circle
double radius; Data Field
// Construct a circle object
Circle()
{
radius = 1;
} Constructors
// Construct a circle object
Circle(double newRadius)
{
radius = newRadius;
}
15
int main()
{
Circle circle1();
()
Circle circle2(25);
Circle circle3(125);
return 0;
}
16
Avoiding Stale Data
• In the Circle class the area of a rectangle is calculated.
radius * radius * 3.14159
• If we were to use an area variable (circle2.area)
its value would be dependent on the radius.
• If we change radius without updating area, then
area would become stale.
• To avoid stale data, calculate the value of that data
within a member function circle2.getArea()
rather than store it in a variable.
17
Access Specifiers
• Used to control access to members of the class
• public: can be accessed by functions outside of
the class
• private: can only be called by or accessed by
functions that are members of the class
• If not specified, the default is private
18
Example: Defining Classes and
Creating Objects
-
-
-
19
class TV
{
private:
int channel;
int volumeLevel; // Default volume level is 1
bool on; // By default TV is off
public:
TV()
{
channel = 1; // Default channel is 1
volumeLevel = 1; // Default volume level is 1
on = false; // By default TV is off
}
void turnOn()
{
on = true;
}
void turnOff()
{
on = false;
}
… 20
class TV
{
…
void setChannel(int newChannel)
{
if (on && newChannel >= 1 && newChannel <= 120)
channel = newChannel;
}
void channelUp()
{
if (on && channel < 120)
channel++;
}
…
21
class TV
{
…
void channelDown()
{
if (on && channel > 1)
channel--;
}
void volumeUp()
{
if (on && volumeLevel < 7)
volumeLevel++;
}
void volumeDown()
{
if (on && volumeLevel > 1)
volumeLevel--;
}
};
22
int main()
{
TV tv1;
tv1.turnOn();
tv1.setChannel(30);
tv1.setVolume(3);
TV tv2;
tv2.turnOn(); Access Problem
tv2.channelUp(); here??
tv2.channelUp();
tv2.volumeUp();
return 0;
23
Constructors
Has the same name as the defining class.
Can be overloaded making it easy to construct objects with
different initial data values.
Do not have a return type—not even void.
Play the role of initializing objects.
A class normally provides a constructor without arguments
(no-arg or no-argument constructor)
e.g: Circle(), TV()
A class may be declared without constructors.
A no-arg constructor with an empty body is implicitly
declared (a default constructor) 24
Naming Objects and
Classes
• When you declare a custom class, capitalize the first
letter of each word in a class name; for example, the
class names Circle, Rectangle, and TV.
• The class names in the C++ library are named in
lowercase.
• The objects are named like variables.
TV tv1; // no-arg constructor
TV tv2(3); // constructor with
arguments
25
Memberwise Copy
Use the assignment operator =
By default, each data field of one object is copied to its
counterpart in the other object.
For example,
circle2 = circle1;
copies the radius in circle1 to circle2.
After the copy, circle1 and circle2 are still two different
objects, but with the same radius value.
Once an object name is declared, it represents an object
and cannot be reassigned to represent another object.
26
Anonymous Object
• You may create an object and use it only once without
the need to name it (anonymous object)
no-arg
27
Class Replaces struct
The C language has the struct type for representing
records.
C C++
struct Student class Student
{ {
int id; public:
char firstName[30]; int id;
char mi; char firstName[30];
char lastName[30]; char mi;
}; char lastName[30];
};
(a) (b)
28
Separating Definition from
Implementation
Class
ClassName.h ClassName.cpp
Definition Implementation
29
Separating Definition from
Implementation
ClassName.h Circle.h Circle.cpp ClassName.cpp
int main()
{
Circle circle1;
circle1;
Circle circle2(5.0);
circle2(5.0);
// Modify circle
circle radius
radius
circle2.radius
circle2.radius == 100;
100;
cout
cout <<
<< "The
"The area
area of
of the
the circle
circle ofof radius
radius ""
<<
<< circle2.radius
circle2.radius <<
<< "" is
is "" <<
<< circle2.getArea()
circle2.getArea() <<
<< endl;
endl;
return
return 0;
0;
}
}
34
Benefits of Separation
• Hides implementation from definition.
• Feel free to change the implementation.
• The client program does not need to change if the definition is
not changed.
• As a software vendor, just provide the customer with the
header file and class object code without revealing the
source code for implementing the class.
• Protects the software vendor’s intellectual property.
35
Preventing Multiple
Declarations
#include "Circle.h"
Ring.h
// Other code in Ring.h is omitted
#include "Circle.h"
Geometry.cpp #include "Ring.h"
int main()
{
// Other code in Geometry.cpp is
omitted
}
36
inclusion guard
#ifndef CIRCLE_H // preprocessor directive
#define CIRCLE_H
class Circle
{
Circle.h
public:
37
Data Field Encapsulation
The data fields radius in the Circle can be modified
directly
circle1.radius = 5
Not a good practice for two reasons:
• Data may be tampered.
• Makes the class difficult to maintain and vulnerable to
bugs.
• Modifying Circle requires changing the client
programs.
38
Getter (Accessor) and Setter (Mutator)
class TV
{
private:
int channel, volumeLevel;
bool on;
public:
TV();
// returnType getPropertyName()
int getChannel(); // Getter (Accessor)
40
The Scope of Variables
Local variables are declared and used inside a
function locally.
41
The Scope of Variables
class Foo
{
public: int main()
int x; // Data field {
int y; // Data field Foo foo;
foo.p();
Foo()
return 0;
{
}
x = 10;
y = 10;
}
void p()
{
int x = 20; // Local variable
cout << "x is " << x << endl;
cout << "y is " << y << endl;
} 42
Class Abstraction and Encapsulation
43
Example
-
-
-
44
Passing Objects to Functions
You can pass objects by value or by reference, but
it is more efficient to pass objects by reference
void printCircle(Circle&
printCircle(Circle c)
{
cout << "The area of the circle class Circle
of " {
<< c.getRadius() << " is “ public:
Circle();
<< c.getArea() << endl; Circle(double);
} double getArea();
double getRadius();
int main() void
setRadius(double);
{
Circle myCircle(5.0); private: double radius;
printCircle(myCircle); };
return 0;
45
Array of Objects
int main()
{
const int SIZE = 10;
return 0;
}
46
Array of Objects
int main()
{
const int SIZE = 10;
return sum;
}
47
Array of Objects vs Parallel
Arrays
class TV int
int main()
main()
{ {
{
public: int allMyTVsChannel[3];
int allMyTVsChannel[3];
int channel; int allMyTVsVolumeLevel[3];
int
int volumeLevel; bool allMyTVsOn[3];
allMyTVsVolumeLevel[3];
…
bool on;
… bool allMyTVsOn[3];
displayTVstatus(
} … allMyTVsChannel[2],
int main() displayTVstatus(
{ allMyTVsVolumeLevel[2],
… allMyTVsOn[1]);
allMyTVsChannel[2],
… May be an error
TV allMyTVs[3];
return 0;
… allMyTVsVolumeLevel[2],
}
allMyTVsOn[1]);
allMyTVs[2].displayTVstatus();
…
…
return 0;
return 0;
} } 49
48
Instance and Static
Members
• Static variables: All objects of the same class are
affected if one object changes the value of a static
variable.
49
Instance and Static
Members
50
Instance and Static
Members
#ifndef CIRCLE_H Circle.h
#define CIRCLE_H
class Circle
{
public:
Circle();
Circle(double);
double getArea();
double getRadius();
void setRadius(double);
static int getNumberOfObjects();
private:
double radius;
static int numberOfObjects;
};
#endif
51
Instance and Static
Members
#include "CircleWithStaticDataFields.h"
int Circle::numberOfObjects = 0;
Circle.cpp
// Construct a circle object
Circle::Circle()
{
radius = 1;
numberOfObjects++;
}
// Construct a circle object
Circle::Circle(double newRadius)
{
radius = newRadius;
numberOfObjects++; // Can access static and non-static
members
}
// Return the number of circle objects
int Circle::getNumberOfObjects()
{
return numberOfObjects; // Cannot access non-static 52
Instance and Static
Members
#include <iostream>
#include "CircleWithStaticDataFields.h"
using namespace std;
int main() {
cout << "Number of circle objects created: "
<< Circle::getNumberOfObjects() << endl;
Circle circle1;
cout << "The area of the circle of radius "
<< circle1.getRadius() << " is " << circle1.getArea() <<
endl;
cout << "Number of circle objects created: "
<< Circle::getNumberOfObjects() << endl;
Better
Circle circle2(5.0);
cout << "The area of the circle of radius "
<< circle2.getRadius() << " is " << circle2.getArea() <<
endl;
cout << "Number of circle objects created: "
54
<< circle2.getNumberOfObjects() << endl; 53
Instance or Static?
How do you decide whether a variable or function should
be instance or static?
A variable or function that is dependent on a specific
instance of the class should be an instance variable or
function.
A variable or function that is not dependent on a
specific instance of the class should be a static variable
or function.
54
Constant Member Functions
You can use const to specify a constant parameter.
55
Constant Member Functions
#ifndef CIRCLE_H
#define CIRCLE_H
class Circle
{
public:
Circle();
Circle(double);
double getArea() const;
double getRadius() const; Cannot be
void setRadius(double); static
static int getNumberOfObjects();
Cannot be const
private:
double radius;
static int numberOfObjects;
};
#endif
56
Constant Member Functions
#include "CircleWithConstantMemberFunctions.h"
int Circle::numberOfObjects = 0;
...
57
Constant Member Functions
void printCircle(const Circle& c) // External
function
{
cout << "The area of the circle is " <<
c.getArea();
}
58
Designing a Class
Cohesion
• A class should describe a single entity or a set of similar operations.
Consistency
• Follow standard programming style and naming conventions.
Encapsulation
• Hide data and internal functions.
• Don’t provide a setter for read-only fields.
Clarity
• Don’t restrict what/when a user can use a class member field/method.
Completeness
• Classes are designed for use by many different customers.
• Provide a variety of ways for customization through properties and
functions.
59
Aggregation
• Aggregation: a class is a member of a class
• Nested classes
60
Aggregation
class StudentInfo // Aggregated
{
string fullName, address;
};
61
Aggregation
Composition is a special case of Aggregation
Composition Aggregation
1 1
1 1 Aggregating
1 5 * *
Aggregated Aggregated
63