DEV Community

mohamed Tayel
mohamed Tayel

Posted on

Mastering C# Fundamentals: Introduction to Classes

Meta Description: Learn the fundamentals of C# classes with a practical example. Discover how to create and use a real-world Employee class, complete with properties, methods, and constants to encapsulate data and functionality effectively

When starting to code, most people begin by working with variables like int a = 3. This is a great introduction to understanding how data is stored and manipulated. However, for more complex applications, we need a structured way to represent entities with both data and related behaviors. This is where classes in C# come into play.

In this article, we will explore what classes are, why they are useful, and how to create them in C#. We'll use an Employee class as an example to demonstrate how we can encapsulate both data and functionality into one unit, making it easier to manage, reuse, and maintain.

What is a Class?

A class in C# is a blueprint for creating objects—instances that represent real-world entities. Classes help encapsulate data (properties) and functionality (methods) into a single logical unit. This is a core concept of object-oriented programming (OOP), enabling developers to write more modular, reusable, and organized code.

Think of a class like a blueprint for a house: the blueprint itself isn’t the house, but it provides the plan to create one. Similarly, a class is a template, and the objects created from it are instances of that template.

The Employee Class Example

Let’s dive into an example. We will create an Employee class that encapsulates different attributes of an employee along with various methods that define what an employee can do.

Here is our updated Employee class:

public class Employee
{
    // Properties to store data about the employee
    public int EmployeeID { get; set; }
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public string Title { get; set; }
    public string TitleOfCourtesy { get; set; }
    public DateTime? BirthDate { get; set; }
    public DateTime? HireDate { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string Region { get; set; }
    public string PostalCode { get; set; }
    public string Country { get; set; }
    public string HomePhone { get; set; }
    public string Extension { get; set; }
    public byte[] Photo { get; set; }
    public string Notes { get; set; }
    public int? ReportsTo { get; set; }
    public string PhotoPath { get; set; }

    // Constant to represent default values
    private const double defaultHourlyRate = 20.0;
    private const int minimalHoursWorkedUnit = 1;

    // Field to store hours worked and hourly rate
    private int numberOfHoursWorked;
    private double hourlyRate;

    // Constructor to initialize the employee
    public Employee(int employeeID, string firstName, string lastName, double hourlyRate = defaultHourlyRate)
    {
        EmployeeID = employeeID;
        FirstName = firstName;
        LastName = lastName;
        this.hourlyRate = hourlyRate;
        numberOfHoursWorked = 0; // Initialize hours worked to zero
    }

    // Method to perform work for the minimum unit of hours
    public void PerformWork()
    {
        PerformWork(minimalHoursWorkedUnit);
    }

    // Overloaded method to perform work for a given number of hours
    public void PerformWork(int hours)
    {
        numberOfHoursWorked += hours;
        Console.WriteLine($"{FirstName} {LastName} has worked for {numberOfHoursWorked} hours.");
    }

    // Method to receive payment
    public double ReceivePay(bool resetHours = true)
    {
        double wage = numberOfHoursWorked * hourlyRate;
        Console.WriteLine($"{FirstName} {LastName} has been paid {wage:C}.");

        if (resetHours)
        {
            numberOfHoursWorked = 0;
        }

        return wage;
    }

    // Method to update the employee's address
    public void UpdateAddress(string newAddress, string newCity, string newRegion, string newPostalCode, string newCountry)
    {
        Address = newAddress;
        City = newCity;
        Region = newRegion;
        PostalCode = newPostalCode;
        Country = newCountry;

        Console.WriteLine($"{FirstName} {LastName}'s address has been updated.");
    }

    // Method to display full employee information
    public void DisplayEmployeeDetails()
    {
        Console.WriteLine($"Employee ID: {EmployeeID}");
        Console.WriteLine($"Name: {TitleOfCourtesy} {FirstName} {LastName}");
        Console.WriteLine($"Title: {Title}");
        Console.WriteLine($"Address: {Address}, {City}, {Region}, {Country}");
        Console.WriteLine($"Hire Date: {HireDate?.ToString("d")}");
        Console.WriteLine($"Reports To: {(ReportsTo.HasValue ? ReportsTo.ToString() : "None")}");
    }
}
Enter fullscreen mode Exit fullscreen mode

Breakdown of the Employee Class

  1. Properties: The Employee class has a range of properties representing the various details of an employee, such as EmployeeID, FirstName, LastName, Address, etc. These properties hold the state of each employee.

  2. Constants:

    • defaultHourlyRate: Set to 20.0, this represents the default pay rate per hour.
    • minimalHoursWorkedUnit: Represents the smallest unit of hours worked, which is 1 hour. Using constants like these ensures consistency and avoids magic numbers.
  3. Fields:

    • numberOfHoursWorked and hourlyRate are private fields that maintain the internal state of hours worked and the pay rate for each employee.
  4. Constructor:

    • The constructor initializes essential employee information, such as EmployeeID, FirstName, LastName, and optionally the hourlyRate.
  5. Methods:

    • PerformWork(): Simulates work performed by the employee. The no-parameter version increments hours worked by the minimum unit, while the overloaded version allows specifying a number of hours.
    • ReceivePay(): Calculates and displays the employee's wage. It also optionally resets the hours worked.
    • UpdateAddress(): Updates the employee’s address, making it easy to modify the location in one go.
    • DisplayEmployeeDetails(): Displays all the details of the employee, useful for viewing information in a formatted way.

Practical Example of Using the Employee Class

Now, let’s use the Employee class in a simple program to see how it works:

public class Program
{
    public static void Main()
    {
        // Creating an Employee object
        Employee johan= new Employee(1, "Johan", "Wick");

        // Displaying initial employee details
        johan.DisplayEmployeeDetails();

        // Performing work
        johan.PerformWork(); // Output: Bethany Smith has worked for 1 hours.
        johan.PerformWork(4); // Output: Bethany Smith has worked for 5 hours.

        // Receiving payment
        double pay = johan.ReceivePay(); // Output: Bethany Smith has been paid $100.00.

        // Updating employee address
        johan.UpdateAddress("456 New St", "Los Angeles", "CA", "90001", "USA");
        // Output: Bethany Smith's address has been updated.

        // Displaying updated employee details
        johan.DisplayEmployeeDetails();
    }
}
Enter fullscreen mode Exit fullscreen mode

Key Concepts Explained

  1. Constants for Reusability:

    • By using defaultHourlyRate and minimalHoursWorkedUnit, we avoid magic numbers in the code. These constants make the code more readable and easier to maintain.
  2. Encapsulation:

    • The Employee class encapsulates both the data (attributes like FirstName, Address) and behavior (methods like PerformWork(), ReceivePay()). This approach makes the class cohesive, with a clear separation of concerns, which helps keep code organized and understandable.
  3. Properties vs. Fields:

    • Properties are used to expose data to the outside world, while fields like numberOfHoursWorked and hourlyRate are kept private to maintain control over the internal state. This is a great example of data encapsulation—a key principle of OOP.
  4. Method Overloading:

    • PerformWork() is overloaded to allow different ways of specifying how much work the employee has done. This provides flexibility in how we use the class.

Conclusion

The Employee class is a perfect demonstration of how classes allow us to model real-world entities in C#. By grouping data (properties) and functionality (methods) into one logical unit, we achieve a clean, reusable, and maintainable structure.

In this article, we covered:

  • What classes are and why they are important.
  • How to create and use an Employee class, with a detailed example.
  • The addition of constants and methods to make the class functional and practical for real-world scenarios.

Classes are at the core of object-oriented programming and are crucial for writing maintainable and modular code. As you continue your journey in C#, you will build on these concepts .

Top comments (0)