Object-Oriented Programming

Object-oriented programming is another way of thinking about programming.  Here the focus is on the relationship between data and tasks, rather than on a program's tasks.  In object-oriented programming, a program contains objects that respond to messages sent to them.  A message (function call) is simply a request for the object to do something.

In C++, you create objects that contain data (attributes) and actions or behaviours that the object is capable of performing.  You implement these actions, called methods (or member functions), by writing functions that are part of the object itself.

Data Encapsulation

An object-oriented language must provide support for data encapsulation.  Data encapsulation refers to the process of hiding or encapsulating data within an object.  In object-oriented programming, data and the functions that operate on that data are part of a single item, which is referred to as an object.  The data are called data members (attributes) and the functions are called methods (or member functions).

The details of the implementation (data) are encapsulated within the class, which means that the data are hidden from the class's users by keeping the data inaccessible to them.  Instead, the class's users must use one of the methods.  The methods have direct access to the data between the data are encapsulated or hidden in the class.

Because C++ supports encapsulation, changes made to the representation of the data members will affect only the methods of the class.  Although the class author might need to rewrite the methods to accomodate the changes to the representation of the data, you do not need to change programs that were written using the class.  That's because the user of the class -- a programmer -- used the class interface (methods) and did not worry about the implementation details.

Example:  Hockey Team class

It is possible to change the implementation of our hockey team class to use C++ standard library string objects instead of C-style strings (char *).  Because of encapsulation, no code that uses the class has to change:

Listing 1A. HockeyTeam.h using C++ string objects

#if !defined(__HOCKEY_TEAM_H__)
#define __HOCKEY_TEAM_H__

#include <string>

using namespace std;

//
//  Class to model a hockey team
//

class HockeyTeam
{
private:
	string	itsConference;		// Conference
	string	itsDivision;		// Division
	string	itsName;		// Name of team (city)
	int	itsWins;		// Number of games won
	int	itsLosses;		// Number of games lost
	int	itsTies;		// Number of games tied
	int	itsGoalsFor;		// Total goals scored by this team
	int	itsGoalsAgainst;	// Total goals scored against this team
	int	itsPoints;		// Total number of points

public:
	HockeyTeam( const char * theName );	// "Constructor"
	~HockeyTeam( );				// "Destructor"

	// "Accessors"

	const char *	getConference( ) const	
				{ return itsConference.data( ); }
	const char *	getDivision( ) const	
				{ return itsDivision.data( ); }
	const char *	getName( ) const	 
				{ return itsName.data( ); }

	int 		getWins( ) const 	 { return itsWins; }
	int 		getLosses( ) const 	 { return itsLosses; }
	int 		getTies( ) const 	 { return itsTies; }
	int 		getGoalsFor( ) const 	 { return itsGoalsFor; }
	int 		getGoalsAgainst( ) const { return itsGoalsAgainst; }
	int 		getPoints( ) const	 { return itsPoints; }

	int		gamesPlayed( ) const
			{ return itsWins + itsTies + itsLosses; }

	// "Mutators"

	void		setConference( const char * theConference );
	void		setDivision( const char * theDivision );
	void		changeName( const char * theName );

	void 		reorganize( const char * theConference, 
				    const char * theDivision );

	void		applyGame( int goalsFor, int goalsAgainst );
	void		applyGame( int goalsFor, int goalsAgainst, bool bOT );
};

//////////////////////////////////////////////////////////////////////////
//  Function:		operator<<
//  Description:	team insertion operator
//  Parameters:		ostr - an output stream, theTeam - a team
//  Returns:		ostr
//////////////////////////////////////////////////////////////////////////
inline ostream &
operator<<( ostream & ostr, const HockeyTeam & theTeam )
{
	ostr << theTeam.getConference( ) << ' ';
	ostr << theTeam.getDivision( ) << ' ';
	ostr << theTeam.getName( ) << ' ';
	ostr << theTeam.getWins( ) << ' ';
	ostr << theTeam.getLosses( ) << ' ';
	ostr << theTeam.getTies( ) << ' ';
	ostr << theTeam.getGoalsFor( ) << ' ';
	ostr << theTeam.getGoalsAgainst( ) << ' ';
	ostr << theTeam.getPoints( );
	return ostr;
}

#endif /* __HOCKEY_TEAM_H__ */

Download this file

Listing 1B. HockeyTeam.cpp using C++ string objects

#include "HockeyTeam.h"
#include <iostream>
#include <string>

HockeyTeam::HockeyTeam( const char * theName ) :
	// "Memberwise initialization"
	itsConference( ),
	itsDivision( ),
	itsName( ),
	itsWins( 0 ),
	itsLosses( 0 ),
	itsTies( 0 ),
	itsGoalsFor( 0 ),
	itsGoalsAgainst( 0 ),
	itsPoints( 0 )
{
	changeName( theName );
}

HockeyTeam::~HockeyTeam( )
{
	;
}

void		
HockeyTeam::setConference( const char * theConference )
{
	if ( theConference != 0 )
	{
		itsConference = theConference;
	}
}

void		
HockeyTeam::setDivision( const char * theDivision )
{
	if ( theDivision != 0 )
	{
		itsDivision = theDivision;
	}
}

void		
HockeyTeam::changeName( const char * theName )
{
	if ( theName != 0 )
	{
		itsName = theName;
	}
}

void 		
HockeyTeam::reorganize( const char * theConference, const char * theDivision )
{
	if ( ( theConference != 0 ) && ( theDivision != 0 ) )
	{
		setConference( theConference );
		setDivision( theDivision );
	}
}

void		
HockeyTeam::applyGame( int goalsFor, int goalsAgainst )
{
	applyGame( goalsFor, goalsAgainst, false );
}

void		
HockeyTeam::applyGame( int goalsFor, int goalsAgainst, bool bOvertime )
{
	itsGoalsFor += goalsFor;
	itsGoalsAgainst += goalsAgainst;

	if ( goalsFor > goalsAgainst )
	{
		itsPoints += 2;
		itsWins += 1;
	}
	else if ( goalsFor < goalsAgainst )
	{
		itsLosses += 1;
		if ( bOvertime )
		{
			itsPoints += 1;
		}
	}
	else	// must be == (a tie)
	{
		itsTies += 1;
		itsPoints += 1;
	}
}

Download this file

Listing 1C. testHockeyTeam.cpp using C++ string objects

#include <iostream>
#include "HockeyTeam.h"

int
main( )
{
	HockeyTeam leafs( "Toronto Maple Leafs" );

	leafs.reorganize( "Eastern", "Northeast" );

	leafs.applyGame( 4, 3 );		// 4 - 3 regulation time win
	leafs.applyGame( 4, 5, true );		// 5 - 4 overtime loss 

	cout << "In " << leafs.gamesPlayed( ) << " games: " << endl;
	cout << leafs << endl;
	
	return 0;
}

Download this program

The only minor change to testHockeyTeam.cpp is the #include <iostream> instead of #include <iostream.h>.  This is because the string class is part of the C++ standard library.  As a result, we have to use the C++ standard library version of the iostream library, too.

Download an alternate version of this program
Download another alternate version of this program


Back to the COMP435 page