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.
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.
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.
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.
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.
In this lesson, we have explored the concept of encapsulation in C#.
{ get; set; }
), which simplifies the declaration of properties by automatically generating the underlying private fields.As you continue to develop your skills, keep practicing encapsulation to create robust and maintainable code. Good luck with the practices, and happy coding!