Lesson 2
Revisiting Encapsulation in C#
Revisiting Encapsulation

Welcome back! After diving deep into classes in our last session, we're now shifting our focus to another essential concept in Object-Oriented Programming (OOP): encapsulation.

Encapsulation bundles data (fields) and methods (functions) that operate on the data, restricting direct access to some of an object's components. This prevents accidental modification of data by keeping the data attributes private and providing public methods to access and modify them. By ensuring that the internal state of the object can only be changed in controlled ways, you can maintain consistency and prevent errors.

Create Private Fields

Let's start by defining a simple Person class with private fields. To apply encapsulation, we need to make the fields private by using the private keyword:

C#
1public class Person 2{ 3 // Private fields for encapsulation 4 private string name; 5 private int age; 6 7 // Constructor to initialize private fields 8 public Person(string name, int age) 9 { 10 this.name = name; 11 this.age = age; 12 } 13}

Now, name and age are private fields, meaning they cannot be accessed directly from outside the Person class. Instead, we will provide public accessors to interact with these fields.

Properties for Accessors

In C#, we commonly use properties to provide controlled access to private fields. Properties are a cleaner and more idiomatic way to implement getters and setters in C#:

C#
1public class Person 2{ 3 // Private fields for encapsulation 4 private string name; 5 private int age; 6 7 // Constructor to initialize private fields 8 public Person(string name, int age) 9 { 10 this.name = name; 11 this.age = age; 12 } 13 14 // Property for accessing and modifying 'name' field 15 public string Name 16 { 17 get { return name; } 18 set { name = value; } 19 } 20 21 // Property for accessing and modifying 'age' field 22 public int Age 23 { 24 get { return age; } 25 set { age = value; } 26 } 27}

In this example, the Name and Age properties use getter and setter methods to provide controlled access to the private name and age fields.

Auto-Implemented Properties

In addition to defining custom getters and setters, C# provides a more concise syntax called auto-implemented properties. This allows you to define properties without explicitly declaring private fields:

C#
1public class Person 2{ 3 // Auto-implemented properties for 'Name' and 'Age' 4 public string Name { get; set; } 5 public int Age { get; set; } 6 7 // Constructor to initialize properties 8 public Person(string name, int age) 9 { 10 Name = name; 11 Age = age; 12 } 13}

With auto-implemented properties, the compiler automatically creates a private, anonymous backing field that can only be accessed through the property's get and set accessors. This can make the code more concise and readable while still providing controlled access to the fields.

Test the Encapsulation

Let's use our Person class to see encapsulation in action. We will create an instance of Person, access its fields through the properties, and modify them via the properties:

C#
1public class Program 2{ 3 static void Main() 4 { 5 Person person = new Person("Alice", 30); 6 7 // Accessing private fields through properties 8 Console.WriteLine($"Name: {person.Name}, Age: {person.Age}"); // Output: Name: Alice, Age: 30 9 10 // Modifying private fields through properties 11 person.Name = "Bob"; 12 person.Age = 25; 13 14 // Accessing modified fields 15 Console.WriteLine($"Name: {person.Name}, Age: {person.Age}"); // Output: Name: Bob, Age: 25 16 } 17}

Here, we have encapsulated the name and age fields by making them private and providing properties for controlled access and modification.

Conclusion

In this lesson, we have explored the concept of encapsulation in C#.

  • We defined private fields in a class and provided controlled access to these fields using properties.
  • We discovered that C# also allows for a more concise syntax through auto-implemented properties ({ get; set; }), which simplifies the declaration of properties by automatically generating the underlying private fields.
  • Encapsulation helps in protecting the integrity of the data and makes your code modular and easier to maintain.

As you continue to develop your skills, keep practicing encapsulation to create robust and maintainable code. Good luck with the practices, and happy coding!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.