DEV Community

mohamed Tayel
mohamed Tayel

Posted on

Mastering C# Fundamentals: The Has-A Relationship

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; }
    }
}
Enter fullscreen mode Exit fullscreen mode

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; }
    }
}
Enter fullscreen mode Exit fullscreen mode

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}");
    }
}
Enter fullscreen mode Exit fullscreen mode

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 and Book classes.
  • Book should have properties like Title and Publisher.
  • Create an instance of Book and Publisher 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 with Department.
  • 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 an Address and belongs to a Classroom.
  • A Classroom class that contains a list of Student objects.
  • A Teacher class, where each teacher has an Address and is responsible for a Classroom.
  • Instantiate all these classes and establish relationships between them.

Steps to Follow:

  • Create Student, Classroom, and Teacher classes.
  • Establish the Has-A relationships:
    • Student has an Address and belongs to a Classroom.
    • Teacher has an Address and is assigned to a Classroom.
  • 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)