Object Composition C# Example
--
Object composition is a fundamental concept in object-oriented programming (OOP) that refers to the practice of creating complex objects or systems by combining simpler objects, or components, in a way that allows them to work together to achieve a higher-level functionality. It’s a key principle that promotes reusability, modularity, and flexibility in software design.
Here are some key points to understand about object composition:
- Composition Over Inheritance: Object composition is often favored over inheritance as a means of building complex objects. Inheritance (subclassing) can lead to tight coupling between classes, making the system less flexible and harder to maintain. Composition, on the other hand, promotes loose coupling and greater flexibility.
- Components: In object composition, components are individual objects with specific responsibilities or functionalities. These components can be instances of different classes, and they are combined to create a more complex object.
- Has-A Relationship: Object composition typically represents a “has-a” relationship, where an object contains or is composed of other objects. For example, a car “has-a” engine, and a computer “has-a” CPU.
- Encapsulation: Each component in the composition maintains its own state and behavior, encapsulating its functionality. This encapsulation allows for easy modification of individual components without affecting the entire composition.
- Flexibility: Object composition allows you to create new objects with different combinations of components, leading to highly flexible and configurable systems. You can swap out components or add/remove them as needed.
- Code Reusability: By using object composition, you can reuse existing components across different objects or systems. This promotes the DRY (Don’t Repeat Yourself) principle and reduces code duplication.
- Interface-Based: Components in object composition often adhere to interfaces or abstract classes, defining a contract that specifies the methods and properties they must implement. This enforces a consistent interface for interacting with components.
- Example: Consider a graphical user interface (GUI) framework. Instead of creating a monolithic “Widget” class that incorporates all possible UI elements (buttons, text fields, etc.), you can use object composition to build a UI by combining individual components like buttons, text fields, and panels.
Object composition in C# involves creating complex objects by combining simpler objects or components. Here’s an example in C# that demonstrates object composition to build a simple application for managing employees in a company. We’ll create classes for employees, departments, and a company that uses object composition:
💻 Employee Class
using System;
using System.Collections.Generic;
// Employee class represents individual employees
class Employee
{
public string Name { get; set; }
public int EmployeeId { get; set; }
public decimal Salary { get; set; }
public Employee(string name, int employeeId, decimal salary)
{
Name = name;
EmployeeId = employeeId;
Salary = salary;
}
public void DisplayInfo()
{
Console.WriteLine($"Employee ID: {EmployeeId}");
Console.WriteLine($"Name: {Name}");
Console.WriteLine($"Salary: ${Salary}");
}
}
💻 Company Class
// Company class represents a company containing multiple departments
class Company
{
public string CompanyName { get; set; }
public List<Department> Departments { get; set; }
public Company(string companyName)
{
CompanyName = companyName;
Departments = new List<Department>();
}
public void AddDepartment(Department department)
{
Departments.Add(department);
}
public void DisplayInfo()
{
Console.WriteLine($"Company: {CompanyName}");
Console.WriteLine("Departments:");
foreach (var department in Departments)
{
Console.WriteLine("===============================");
department.DisplayInfo();
}
}
}
💻 Department Class
// Department class represents a department containing employees
class Department
{
public string DepartmentName { get; set; }
public List<Employee> Employees { get; set; }
public Department(string departmentName)
{
DepartmentName = departmentName;
Employees = new List<Employee>();
}
public void AddEmployee(Employee employee)
{
Employees.Add(employee);
}
public void DisplayInfo()
{
Console.WriteLine($"Department: {DepartmentName}");
Console.WriteLine("Employees:");
foreach (var employee in Employees)
{
Console.WriteLine("===============================");
employee.DisplayInfo();
}
}
}
💻 Execute Program: Main.cs
using ObjectComposition;
// Creating employees
var employee1 = new Employee("John Doe", 101, 60000.00m);
var employee2 = new Employee("Jane Smith", 102, 55000.00m);
// Creating a department and adding employees
var hrDepartment = new Department("HR Department");
hrDepartment.AddEmployee(employee1);
hrDepartment.AddEmployee(employee2);
// Creating another department
var itDepartment = new Department("IT Department");
// Creating a company and adding departments
var myCompany = new Company("MyCompany");
myCompany.AddDepartment(hrDepartment);
myCompany.AddDepartment(itDepartment);
// Displaying company information
myCompany.DisplayInfo();
// Additional operations can be performed on the company, departments, and employees as needed.
Output:
In this example:
Employee
,Department
, andCompany
are classes that represent individual employees, departments, and a company.- Object composition is achieved by creating instances of these classes and organizing them hierarchically. The
Company
contains multipleDepartment
objects, each of which contains multipleEmployee
objects. - The
DisplayInfo
methods are used to print information about employees, departments, and the company.
This example demonstrates how object composition can be used to create a structured hierarchy of objects, making it easier to manage and work with complex systems using C#.
In conclusion, object composition is a powerful design principle in software development, and it enables the construction of flexible, modular, and maintainable systems. By carefully assembling and reusing components, you can create complex objects with well-defined responsibilities, leading to more efficient and adaptable code.