Meta Description:Learn about the Has-A relationship in C# through composition. Understand how to model real-world relationships, create an Address class, and link it to an Employee class with step-by-step examples and practice assignments ranging from easy to challenging.
In object-oriented programming, we often talk about the relationships between different classes and objects. A common type of relationship is the "Is-A" relationship, which we use to establish inheritance. However, another equally important relationship is the "Has-A" relationship, which indicates that one class contains an instance of another class. This kind of relationship is also known as composition.
The Concept of Composition (Has-A Relationship)
To understand the Has-A relationship, let’s consider an example with an Employee
class. Suppose we want to add information about where an employee lives, such as their address. Instead of adding individual properties like street
, houseNumber
, zipCode
, and city
to the Employee
class, we create a new class called Address
and let the Employee
contain an instance of this Address
class.
By doing so, the Employee
class has an address—hence the term Has-A relationship. This relationship signifies that the Address
is a part of the Employee
rather than the Employee
being a type of Address
.
Practical Example: Implementing the Address Class in C
Let's see how to implement this in Visual Studio:
Step 1: Create the Address
Class
We'll start by creating a new class called Address
. This class will simply contain some data about an address:
public class Address
{
private string street;
private string houseNumber;
private string zipCode;
private string city;
// Constructor
public Address(string street, string houseNumber, string zipCode, string city)
{
this.street = street;
this.houseNumber = houseNumber;
this.zipCode = zipCode;
this.city = city;
}
// Properties to get and set data
public string Street
{
get { return street; }
set { street = value; }
}
public string HouseNumber
{
get { return houseNumber; }
set { houseNumber = value; }
}
public string ZipCode
{
get { return zipCode; }
set { zipCode = value; }
}
public string City
{
get { return city; }
set { city = value; }
}
}
The Address
class contains basic information about an address, including street
, houseNumber
, zipCode
, and city
. We’ve added a constructor to initialize these fields and properties to allow getting and setting these values.
Step 2: Add the Address to the Employee Class
Now, let's add an Address
to our Employee
class:
public class Employee
{
private string firstName;
private string lastName;
private Address address;
// Constructor without Address
public Employee(string firstName, string lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
// Constructor with Address information
public Employee(string firstName, string lastName, string street, string houseNumber, string zipCode, string city)
{
this.firstName = firstName;
this.lastName = lastName;
this.address = new Address(street, houseNumber, zipCode, city);
}
// Property to access Address
public Address Address
{
get { return address; }
set { address = value; }
}
// Properties to get and set first and last names
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
}
In the Employee
class, we've added an Address
field and a property to access it. We also created an overloaded constructor that accepts address information to initialize the Address
instance.
Step 3: Using the Composition
Finally, let’s see how we use this in the main program:
public class Program
{
public static void Main()
{
// Create a new Employee using the constructor with Address
Employee jake = new Employee("Jake", "Smith", "123 Main St", "42", "90210", "Los Angeles");
// Accessing the Address property
Console.WriteLine($"Employee: {jake.FirstName} {jake.LastName}");
Console.WriteLine($"Address: {jake.Address.Street}, {jake.Address.HouseNumber}, {jake.Address.ZipCode}, {jake.Address.City}");
}
}
In the above example, we create an Employee
object named Jake
, providing his personal information along with his address. We can then access the nested Address
properties through the Employee
object.
Assignments to Practice Composition
To help understand the concept of composition thoroughly, let's look at three levels of assignments that gradually increase in complexity.
Assignment Level 1: Easy
Create a Book
class that contains a Publisher
class as one of its properties. The Publisher
class should contain basic information such as Name
and Address
. Instantiate a Book
object and assign a Publisher
to it, then print the details of both the book and the publisher.
Steps to Follow:
- Create
Publisher
andBook
classes. -
Book
should have properties likeTitle
andPublisher
. - Create an instance of
Book
andPublisher
and link them together.
Assignment Level 2: Medium
Expand the Employee
example to include a Department
class. Each Employee
should have an associated Department
, and the Department
should contain information such as DepartmentName
and ManagerName
. Instantiate an Employee
and assign them to a Department
, and then print the complete details.
Steps to Follow:
- Create a
Department
class. - Add a property in
Employee
to associate it withDepartment
. - Demonstrate the Has-A relationship by instantiating and linking them.
Assignment Level 3: Difficult
Create a school system consisting of multiple classes:
- A
Student
class that has anAddress
and belongs to aClassroom
. - A
Classroom
class that contains a list ofStudent
objects. - A
Teacher
class, where each teacher has anAddress
and is responsible for aClassroom
. - Instantiate all these classes and establish relationships between them.
Steps to Follow:
- Create
Student
,Classroom
, andTeacher
classes. - Establish the Has-A relationships:
-
Student
has anAddress
and belongs to aClassroom
. -
Teacher
has anAddress
and is assigned to aClassroom
.
-
- Demonstrate how to access nested data, such as listing all students in a classroom or getting the address of a specific student.
Conclusion
The Has-A relationship is a powerful way to model real-world relationships using composition in object-oriented programming. Instead of using inheritance, composition allows us to create more flexible and modular classes, promoting code reuse and better encapsulation. By following the assignments provided, you can gain hands-on experience with this concept and see how composition can be effectively used in building scalable applications.
Top comments (0)