OOP (Object-Oriented Programming) aggregation is a relationship between two classes where one class contains an instance of another class as a member. It represents a "has-a" relationship, where one class has a composition of another class.
In aggregation, the contained class (referred to as the "part" class) can exist independently, and it can be shared by multiple instances of the containing class (referred to as the "whole" class). The lifespan of the part object is not controlled by the whole object. In other words, if the whole object is destroyed, the part object can still exist.
Aggregation is often represented by a member variable of one class being an object of another class. The whole class can access the members of the part class and use its functionality.
In summary, OOP aggregation represents a "has-a" relationship between classes, where one class contains an instance of another class as a member. It provides a way to represent complex relationships and build more flexible and reusable code structures.
Code Example
Address header file
// Address.hpp // Aggregation Example // Created by Kevin Roark on 6/16/23. #ifndef Address_hpp #define Address_hpp #include <string> using namespace std; class Address { private: //class attributes / properties string street; string city; string state; string zip; public: // Getter methods string getStreet() const; string getCity() const; string getState() const; string getZip() const; // Setter methods void setStreet(string newStreet); void setCity(string newCity); void setState(string newState); void setZip(string newZip); //Class Methods string print() const; //constructor Address(string street, string city, string state, string zip); Address(); // default constructor Address(const Address& source); // Copy constructor }; #endif /* Address_hpp */
This is a C++ header file for the Address
class. The class has private member variables (or properties) - street
, city
, state
, and zip
.
This class is a typical example of a Plain Old Data (POD) structure where the member variables are private and are accessed through public getter and setter methods. Getter methods return the value of the member variables, and setter methods modify the value of the member variables.
The class also provides a print
method to output the address information.
The Address
class provides three constructors:
A parameterized constructor that takes four strings (street, city, state, zip). This constructor is used when you want to create an instance of the
Address
class and you have all the information at hand.A default constructor that takes no arguments. This constructor will be used when you want to create an instance of the
Address
class but you do not have any information at hand at the time of creation.A copy constructor that takes a reference to another
Address
object. The copy constructor is a special constructor used for creating a new object as a copy of an existing object. The copy constructor is needed when you want to make a copy of an object to prevent modifications to the original object, for example.
The #ifndef
, #define
, and #endif
preprocessor directives are used to prevent double inclusion of the header file. When the preprocessor sees the #include "Address.hpp"
directive, it checks if Address_hpp
has been defined. If not, it defines it and includes the contents of the header file. If it has already been defined, it skips the contents. This can be helpful in larger programs where multiple files might include the Address.hpp
header file.
Code File for Address
// Address.cpp // Aggregation Example // Created by Kevin Roark on 6/16/23. #include <string> #include <iostream> #include "Address.hpp" //Getter methods string Address::getStreet() const { return street; } string Address::getCity() const { return city; } string Address::getState() const { return state; } string Address::getZip() const { return zip; } //Setter Methods void Address::setStreet(string street) { this->street = street; } void Address::setCity(string newCity) { city = newCity; } void Address::setState(string newState) { state = newState; } void Address::setZip(string newZip) { zip = newZip; } //Class Methods string Address::print() const { string myReturn = ""; myReturn += this->getStreet() + "\n" + this->getCity() + ", "; myReturn += getState() + "\n" + getZip(); return myReturn; } //constructors Address::Address(string street, string city, string state, string zip) { this->street = street; this->city = city; this->state = state; this->zip = zip; } Address::Address() { street = "NA"; city = "NA"; state = "NA"; zip = "NA"; } // Copy constructor Address::Address(const Address& source) { this->street = source.street; this->city = source.city; this->state = source.state; this->zip = source.zip; }
This is the implementation file for the Address
class, where each method declared in the header file ("Address.hpp") is defined.
Getter Methods: These are methods used to get or retrieve the value of private attributes. Here, methods
getStreet()
,getCity()
,getState()
, andgetZip()
are defined to return the respective attribute values. Theconst
keyword at the end of these methods signifies that these methods won't modify the object's state.Setter Methods: These methods are used to set or change the value of private attributes.
setStreet()
,setCity()
,setState()
, andsetZip()
are defined to set the values of the respective attributes.Class Method:
print()
: This method concatenates all the attributes into a single string and returns that string. It is used to get the whole address as a string in the required format.
Constructors: These are special methods used to initialize objects of a class.
Parameterized constructor (
Address(string, string, string, string)
): This constructor is used to initialize anAddress
object with specific values forstreet
,city
,state
, andzip
.Default constructor (
Address()
): This constructor initializes anAddress
object with default values ("NA" in this case).Copy constructor (
Address(const Address&)
): This constructor creates a newAddress
object that is a copy of an existingAddress
object. It copies the values ofstreet
,city
,state
, andzip
from the source object to the new object.
This class implements the concept of Encapsulation, where the data (attributes) of a class are hidden from outside classes and can only be accessed through public methods (getters and setters). This protects the data from being changed accidentally and provides control over how it's accessed or modified. It's a key principle of Object-Oriented Programming (OOP).
Person header File
// // Person.hpp // Created by Kevin Roark on 6-15-23. #ifndef Person_hpp #define Person_hpp #include <stdio.h> #endif /* Person_hpp */ #include <string> #include "Address.hpp" using namespace std; class Person { private: //class attributes / properties string firstName; string middleName; string lastName; Address homeAddress; public: //getters and setters declarations void print() const; void setName(string first, string middle, string last); void setLastName(string last); void setFirstName(string first); void setMiddleName(string middle); void setAddress(Address myAddress); string getFirstName() const; string getMiddleName() const; string getLastName() const; Address getAddress() const; //constructor Person(string, string, string, Address ); };
This is the header file for the Person
class. The class defines a Person
object with private attributes for first, middle, and last names, and their address. The class provides public methods (getters and setters) to access and modify these attributes. It also provides a constructor to initialize a Person
object with specific values.
Class attributes: These are the properties of the
Person
class.firstName
,middleName
, andlastName
are of typestd::string
and represent the person's first, middle, and last names respectively.homeAddress
is of typeAddress
(another class defined in "Address.hpp"). It is used to store the person's address.
Getters and Setters: These methods provide a way to read and write the private attributes of the class.
setFirstName(string first)
,setMiddleName(string middle)
,setLastName(string last)
: These methods set the first, middle, and last names of the person.setName(string first, string middle, string last)
: This method sets all the names (first, middle, and last) at once.setAddress(Address myAddress)
: This method sets thehomeAddress
attribute.getFirstName() const
,getMiddleName() const
,getLastName() const
: These methods return the first, middle, and last names of the person.getAddress() const
: This method returns thehomeAddress
of the person.
print() method: This method is used to print the details of the
Person
object. The implementation of this method should be in the corresponding .cpp file.Constructor: The constructor (
Person(string, string, string, Address)
) is a special method that is called when an object of thePerson
class is created. It initializes thePerson
object with specific values for first name, middle name, last name, and address.
This class showcases the concept of aggregation, where the Address
class is used as an attribute in the Person
class. An object of the Person
class has an object of the Address
class as part of its state. This is a form of "has-a" relationship (a Person
has an Address
), one of the fundamental relationships in object-oriented design.
Code file for Person
// Person.cpp // Created by Kevin Roark on 6-15-23. // This is a C++ source file that defines a class called "Person". // The class has member functions to manipulate a person's first, middle, and last name. It demostrates aggregation using the Address class // Include necessary header files #include <iostream> // Input/output operations #include <string> // String operations #include "Person.hpp" // User-defined header file for the Person class #include "Address.hpp" //User-defined header file for the Address class using namespace std; // Define the constructor function that initializes the first, middle, and last name of a person using provided parameters and address Person::Person(string first, string middle, string last, Address homeAdd) { firstName = first; middleName = middle; lastName = last; homeAddress = homeAdd; } //PUBLIC METHODS // Define the member function "print" that prints the first, middle, and last name of a person as well as the address from the Address class void Person::print() const { cout << firstName << " " << middleName << " " << lastName << endl; cout << homeAddress.print(); } // SETTERS // Define the member function "setName" that sets the first, middle, and last name of a person void Person::setName(string first, string middle, string last) { firstName = first; middleName = middle; lastName = last; } // Define the member function "setLastName" that sets the last name of a person void Person::setLastName(string last) { lastName = last; } // Define the member function "setFirstName" that sets the first name of a person void Person::setFirstName(string first) { firstName = first; } // Define the member function "setMiddleName" that sets the middle name of a person void Person::setMiddleName(string middle) { middleName = middle; } //GETTERS // Define the member function "getFirstName" that returns the first name of a person string Person::getFirstName() const { return firstName; } // Define the member function "getMiddleName" that returns the middle name of a person string Person::getMiddleName() const { return middleName; } // Define the member function "getLastName" that returns the last name of a person string Person::getLastName() const { return lastName; } Address Person::getAddress() const { return homeAddress; }
This is the implementation file for the Person
class declared in "Person.hpp". Here, all the member functions (or methods) declared in the Person
class are defined. This includes the constructor, getters, setters, and the print
function.
Constructor: The constructor
Person::Person(string first, string middle, string last, Address homeAdd)
is defined to initialize the attributes of aPerson
object with provided values when it is created.Setters: These functions set the values of the respective private attributes of the
Person
class.Person::setName(string first, string middle, string last)
sets the first name, middle name, and last name at once.Person::setFirstName(string first)
,Person::setMiddleName(string middle)
,Person::setLastName(string last)
set the first, middle, and last names individually.
Getters: These functions return the values of the respective private attributes.
Person::getFirstName() const
,Person::getMiddleName() const
,Person::getLastName() const
return the first name, middle name, and last name, respectively.Person::getAddress() const
returns thehomeAddress
of the person.
print
function: ThePerson::print() const
function prints the full name of the person (first, middle, and last names) on one line and then prints the address on the following lines. It uses theprint
function of theAddress
class to print the address.
This file provides the implementations of the functions declared in the Person
class, and demonstrates how a Person
object can use the Address
class through aggregation. In this case, Person
has a member homeAddress
of type Address
, which can be used to store and manipulate the address details of a Person
object.
Driver Program
// Created by Kevin Roark on 6-15-23 // Driver to demo the Person Class and Address class - Aggregation #include <iostream> #include "Person.hpp" using namespace std; int main() { Address home("1 Donore Square", "San Antonio", "Texas", "78229"); Person myPerson("Kevin", "Read", "Roark", home); myPerson.print(); cout << endl; return 0; }
This is the main program that utilizes the Person
and Address
classes to create a Person
object with address information and then print the details.
Let's break it down:
#include <iostream>
: This line includes the standard C++ library for input/output operations.#include "Person.hpp"
: This line includes the header file for thePerson
class, which contains the class definition.using namespace std;
: This line allows for the use of standard library functions without having to prepend them withstd::
.int main()
: This is the main function where the program execution begins.Inside the main function:
Address home("1 Donore Square", "San Antonio", "Texas", "78229");
: Here, an object of theAddress
class is created namedhome
, and it is initialized with the given values.Person myPerson("Kevin", "Read", "Roark", home);
: Here, an object of thePerson
class is created namedmyPerson
, and it is initialized with the given values and thehome
object created above. This is an example of aggregation as theAddress
object is part of thePerson
object.myPerson.print();
: This line calls theprint
method on themyPerson
object, which will print the first name, middle name, last name and the address (by invoking theprint
method of theAddress
class).cout << endl;
: This line simply prints a new line to the console for cleaner output formatting.return 0;
: This line signifies successful termination of the program.
This program is a simple demonstration of creating objects in C++ using user-defined classes, specifically showcasing the concept of aggregation, where one class (Person
) is using another class (Address
) as a data member.