Why to use Encapsulation?


In this article I will explain the concept of Encapsulation and how to implement it with the help of properties. It also sheds light on Why, When and How to use a property. Further It provides detailed explanation for creating a property with accessor and mutator methods and making a property read-only or write-only or read write both.

Encapsulation


Definition: The wrapping up of data and functions into a single unit (called class) is known as Encapsulation.

Introduction


All the programmers familiar to the object oriented programming world knows the above mentioned definition of Encapsulation but very few are aware about it's use and how to implement it in a project. Those who implement most of the time does not know that what they are doing is a technique of encapsulation.

Getting Started


Data Encapsulation is the most striking feature of a class. The data is not accessible to outside world and only those functions which are wrapped in the class can access it.

The function provides the interface between objects data and the program. This insulation of data from direct access by the program is called Data hiding or Information Hiding. This is implemented using the mutator and accessor methods of a property.

Example



Till here we went through the theoretical explanation. But the question is How, When and Why to use it in our projects?

To understand this consider a class A with a private string variable Author as follows.


class A
{
private string Author;

public A()
{
Author = "Sibtain";
}
}


Consider Another class B where I want to access the value of this variable Author. I'll make object of class A and will access the value. But the variable Author is not available for access because it is private.

Image 1 - Accessing Private Variable through class Object










Now the option available is to make the author variable public which will allow it to be accessed form class B but this is a wrong technique.
* What if I don't want the value of Author to be changed through an object of class A ?
* What if I don't want to show the current value of Author but want to allow it to be changed thorugh an object of class A ?
* What if I want to allow the users to see the current value but not to change throug the object of class A?

If I'll make the variable public then I will not be able to achieve this. The value can be accessed and can also be changed through the class' object.

The solution is in the formation of a property for Author variable. Hence the access to a variable's value should always be through a property.


In C#, properties are natural extension of data fields. They are usually known as "smart fields".



Why to use a property?


Use of property for a variable of a class gives you control over the way the value of the variable to be accessed.

A property encapsulates a variable of a class and defines the mode of access i.e. Read-Only, Write-Only or Both.

To understand the above statement add the following code in class A which will create property for variable Author.


public string AuthorName
{
get { return Author; }
set { Author = value; }
}


The name of the property is AuthorName and it encapsulates the private variable Author. It contains the Accessor Method


get { return Author; }


and mutator method


set { Author = value; }


Now if you want to access the value of variable Author from class B, you can access it through this property.

Image 2 - Accessing A Property of an Object










We can access as well as modify or change the value of the Author variable through the property as follows.

Image 3 - Using Property to Get and Set Values












Making a property Read-Only



Using the property we can control what the user can do with the value of the variable.

For example when someone creates the object of class A, then I want the value of the Author variable to be available for accession but it should not be changed or modified through the object of class A. In other words I want to make the author variable Read-Only.
This can be achieved by tailoring the AuthorName property as follows.


public string AuthorName
{
get { return Author; }
}


Now the user (object of class A created in class B) can get the value of Author but will not be able to set it.

Image 4 - Read-Only Property












Making a property Write-Only


Next consider the requirement as vice versa. I want to allow any object of class A to change the value of author variable but no one should be able to see what it's current value. In other words I want to make the variable author Write-Only. For this tailor the AuthorName property as follows.


public string AuthorName
{
set { Author = value; }
}


Image 5 - Write-Only Property










Conclusion


We have learnt the very important concept of encapsulation with its practical implementation using properties.

We have also seen how the mutator and accessor methods of the property give full control over the way the value of the variable of a class to be accessed.

And finally we learned how to tailor the properties in order to make them read-only and write-only.

I hope that this article will add value to your knowledge and you like the simple and clean explanation.

(Don't forget to rate the content and leave your responses.)

Thanks 'n Regards,
Sibtain Masih


Comments

Author: Priya K13 Jul 2011 Member Level: Silver   Points : 1

Hi Sibtain,

Thanks a lot for sharing an interesting, already known topic with a brief explanation,

Its easy to understand.

I have a little doubt that if i m having two objects viz objA and objB of the class A and using objA i have changed value as "Tony", now if i try to access the value of objB.AuthorName, ll it return the default value 'Sibtain' or changed value 'Tony'?, (since both the object ll point to the same memory), Help me out to clear the doubt, thanks in advance.

Author: Sibtain13 Jul 2011 Member Level: Gold   Points : 1

You made a statement "since both the object point to the same memory".

This is a wrong assumption.

Class Acts as a blue print for creating objects which means objA will have its own existence in memory and will not be linked at all to objB.

As both have different memory space and no link in between, so the objB.AuthorName will not show the reflection of the changes made by using objA.AuthorName. Both are independent and different from each other.

If you want to make that happen i.e. changes in one object to be reflected in the other then you have to make the variable static (shared in case of VB.Net).

A static variable of a class has only one copy in the memory and all the objects of the class refer to the same copy. Hence if you change the AuthorName to "Tony" it will get reflected in all the objects of class A.

Author: Priya K13 Jul 2011 Member Level: Silver   Points : 1

Thank u Sibtain !!

for clearing my doubt and for saying abt the use of shared / static variable.

Thanks a lot once again..

Author: Deep Gautam15 Jul 2011 Member Level: Gold   Points : 0

Encapsulation txt is attched.

Deep Gautam

Author: Mahesh Nagar15 Jul 2011 Member Level: Gold   Points : 1

very good topic
from the doubt of priya k encapsulation definition is clear that how both object data are separate and hide information each other .

Author: Pawan Awasthi17 Jul 2011 Member Level: Gold   Points : 1

Nice topic..
very good explanation regarding the encapsulation...
keep it up and contribute more and more...

Guest Author: Aafrin25 Feb 2012

Thank you so much your explanation regarding the topic is very simple & easy to understand..thanks a lot

Author: Ajesh Madhukar Dalvi13 Aug 2012 Member Level: Silver   Points : 5

Understand the object-oriented principle of Encapsulation.
Learn the available modifiers for type members.
Protect object state through properties.
Control access to methods.
Learn how to modify types for assembly encapsulation

What is Encapsulation and How Does It Benefit Me?

In object-oriented programming, you create objects that have state and behavior. An object's state is the data or information it contains. For example, if you have a BankAccount object, its state could be Amount and CustomerName. Behavior in an object is often represented by methods. For example, the BankAccount object's behavior could be Credit, Debit, and GetAmount. This sounds like a nice definition of an object, and it is, but you must also consider how this object will be used.

When designing an object, you must think about how others could use it. In a best-case scenario any program using the object would be well designed and the code would never change. However, the reality is that programs do change often and in a team environment many people touch the same code at one time or another. Therefore, it is beneficial to consider what could go wrong as well as the pristine image of how the object *should* be used.

In the case of the BankAccount object, examine the situation where code outside of your object could access a decimal Amount field or a string CustomerName field. At the point of time that the code is written, everything would work well. However, later in the development cycle, you realize that the BankAccount object should keep track of an int CustomerID rather than string CustomerName because you don't want to duplicate relationships between information (or some other valid reason to alter the definition of internal state). Such changes cause a rippling effect in your code because it was built to use the BankAccount class, as originally designed (with CustomerName being a string), and you must now change code that accesses that state throughout your entire application.

The object-oriented principle of Encapsulation helps avoid such problems, allowing you to hide internal state and abstract access to it though type members such as methods, properties, and indexers. Encapsulation helps you reduce coupling between objects and increases the maintainability of your code.
Type Member Access Modifiers

An access modifier allows you to specify the visibility of code outside a type or assembly. Access modifiers can be applied to either types or type members. A later section on Type Access Modifiers discusses modifiers that can be applied to types. This section discusses those modifiers that apply to type members and how they affect visibility.

Generally, you should hide the internal state of your object from direct access from outside code. Then implement other members, such as methods and properties, that wrap that state. This allows the internal implementation of the state to change at will, while the members wrapping the state can still return a representation of the state that doesn't change. This means that outside code will access your object via members that wrap state and be guaranteed that the type of information extracted is consistent. Additionally, because external code doesn't have access to the internal state of your object, they can't alter that state in an inconsistent manner that could break the way your object works.

The first step in encapsulating object state is to determine what type of access that outside code should have to the members of your type. This is performed with access modifiers. The type of access granted varies from no external access at all to full public access and a few variations in between the extremes. Table 19-1 lists all of the type member access modifiers and explains their meaning.
Table 19-1. Type member access modifiers control what code has access to a specified type member.

Access Modifier Description (who can access)
private Only members within the same type. (default for type members)
protected Only derived types or members of the same type.
internal Only code within the same assembly. Can also be code external to object as long as it is in the same assembly. (default for types)
protected internal Either code from derived type or code in the same assembly. Combination of protected OR internal.
public Any code. No inheritance, external type, or external assembly restrictions.

As you've learned from previous lessons of the C# Tutorial, types contain several types of members, including constructors, properties, indexers, methods, and others. Rather than show you an exhaustive list of all of the permutations of access modifiers you can use with these members, I'll take a more practical approach and describe a sub-set of access modifiers used on properties and methods.
Opening Type Members to public Access

You've seen the public access modifier used in earlier parts of the C# Tutorial. Any time the public access modifier is used on a type member, calling code will be able to access the type member. If you make your type member public, you are giving everyone permission to use it. Listing 19-1 shows an example of using the public access modifier on a method.
Listing 19-1. Declaring a Method with a public Access Modifier: BankAccountPublic.cs

using System;

class BankAccountPublic
{
public decimal GetAmount()
{
return 1000.00m;
}
}

The GetAmount() method in Listing 19-1 is public meaning that it can be called by code that is external to this class. Now, you can write the following code, elsewhere in your program, to use this method:

BankAccountPublic bankAcctPub = new BankAccountPublic();

// call a public method
decimal amount = bankAcctPub.GetAmount();

All you need to do, as shown above, is create an instance of the class that contains the method and then call the method through that instance. Because it is public, you won't have a problem. Remember that the default access for a type member is private, which we'll talk about next. This means that if you forget the public modifier, and didn't use any modifier at all, you would receive a compiler error.
Hiding Type Members with private Access

A private type member is one that can only be accessed by members within the same type. For example, if the BankAccount class has a private member, only other members of the BankAccount class can access or call that member.

Although the default access for type members is private, I prefer to be explicit about my intentions when declaring type members and include the access modifier, rather than rely on defaults. I think it makes the code easier to read and makes it clear to other developers what my true intention is. Listing 19-2 shows how to use the private access modifier and offers an example of why you would want to use it.
Listing 19-2. Declaring a private Field: BankAccountPrivate.cs

using System;

class BankAccountPrivate
{
private string m_name;

public string CustomerName
{
get { return m_name; }
set { m_name = value; }
}
}

It's common to encapsulate the state of your type with properties. In fact, I always wrap my type state in a property. In Listing 19-2, you can see how the name of the customer is held in the m_name field, but it is wrapped (encapsulated) with the CustomerName property. Because m_name is declared as private, code outside the BankAccountPrivate class can't access it directly. They must use the public CustomerName property instead.

Now you can change the implementation of m_name in any way you want. For example, what if you wanted it to be an ID of type int and the CustomerName property would do a search to find the name or what if you wanted to have first and last name values that the CustomerName property could concatenate. There are all kinds of things happening to your code in maintenance that will causes implementation to change. The point is that private members allow the implementation to change without constraining the implementation or causing rippling effects throughout your code base that would have occurred if that external code had access to the members of your type.

The private and public access modifiers are at the two extremes of access, either denying all external access or allowing all external access, respectively. The other access modifiers are like different shades of gray between these two extremes, including the protected modifier, discussed next.
Access for Derived Types with the protected Access Modifier

In some ways, the protected access modifier acts like both the private and public access modifiers. Like private, it only allows access to members within the same type, except that it acts like public only to derived types. Said another way, protected type members can only be accessed by either members within the same type or members of derived types.

Returning to the BankAccount example, what if you needed to call code to close an account? Furthermore, what if there were different types of accounts? Each of these different account types would have their own logic for closing, but the basic process would be the same for all account types. If this sounds to you like the description of Polymorphism, you would be on the right track. Back in Lesson 9, we discussed polymorphism and how it allows us to treat different classes the same way. You may want to refer to Lesson 9 for a refresher before looking at the next example.

In the case of closing an account, there are several things that need to be done like calculating interest that is due, applying penalties for early withdrawal, and doing the work to remove the account from the database. Individually, you don't want any code to call methods of the BankAccount class unless all of the methods are called and each method is called in the right order. For example, what if some code called the method to delete the account from the database and didn't calculate interest or apply penalties? Someone would lose money. Also, if the calling code were to delete the account first then the other methods would run into errors because the account information isn't available. Therefore, you need to control this situation and Listing 19-3 shows how you can do it.
Listing 19-3. Declaring protected Methods: BankAccountProtected.cs

using System;

class BankAccountProtected
{
public void CloseAccount()
{
ApplyPenalties();
CalculateFinalInterest();
DeleteAccountFromDB();
}

protected virtual void ApplyPenalties()
{
// deduct from account
}

protected virtual void CalculateFinalInterest()
{
// add to account
}

protected virtual void DeleteAccountFromDB()
{
// send notification to data entry personnel
}
}

The most important parts of Listing 19-3 are that the CloseAccount method is public and the other methods are protected. Any calling code can instantiate BankAccountProtected, but it can only call the CloseAccount method. This gives you protection from someone invoking the behavior of your object in inappropriate ways. Your business logic is sound.

At the end of this section, you'll see an example of how to call the code in Listing 19-3. For now, it is essential that you see how the other pieces fit together first.

If you only wanted the BankAccountProtected class to operate on its own members, you could have made the protected methods private instead. However, this code supports a framework where you can have different account types such as Savings, Checking, and more. You will be able to add new account types in the future because the BankAccountProtected class is designed to support them with protected virtual methods. Listings 19-4 and 19-5 show you the SavingsAccount and CheckingAccount classes that derive from the BankAccountProtected class.
Listing 19-4. Derived SavingsAccount Class Using protected Members of its Base Class: SavingsAccount.cs

using System;

class SavingsAccount : BankAccountProtected
{
protected override void ApplyPenalties()
{
Console.WriteLine("Savings Account Applying Penalties");
}

protected override void CalculateFinalInterest()
{
Console.WriteLine("Savings Account Calculating Final Interest");
}

protected override void DeleteAccountFromDB()
{
base.DeleteAccountFromDB();
Console.WriteLine("Savings Account Deleting Account from DB");
}
}

Notice how SavingsAccount derives from BankAccountProtected. SavingsAccount can access any of the protected members of the BankAccountProtected class which is its base class. It demonstrates this fact via the call to base.DeleteAccountFromDB in it's DeleteAccountFromDB method. If the inheritance part of Listing 19-4 is a little confusing, you can visit Lesson 8: Class Inheritance for a refresher and better understanding. Each method of SavingsAccount has the protected access modifier also, which simply means that classes derived from SavingsAccount can access those SavingsAccount members with the protected access modifier. The same situation exists with the CheckingAccount class, shown in Listing 19-5.
Listing 19-5. Derived CheckingAccount Class Using protected Members of its Base Class: CheckingAccount.cs

using System;

class CheckingAccount : BankAccountProtected
{
protected override void ApplyPenalties()
{
Console.WriteLine("Checking Account Applying Penalties");
}

protected override void CalculateFinalInterest()
{
Console.WriteLine("Checking Account Calculating Final Interest");
}

protected override void DeleteAccountFromDB()
{
base.DeleteAccountFromDB();
Console.WriteLine("Checking Account Deleting Account from DB");
}
}

The CheckingAccount class in Listing 19-5 is implemented similar to SavingsAccount from Listing 19-4. If you were writing this, the difference would be that the methods of each class would have unique implementations. For example, the business rules associated with the final interest calculation would differ, depending on whether the account type was checking or savings.

Notice the call to the base class method in the DeleteAccountFromDB method in CheckingAccount. Just like SavingsAccount, CheckingAccount has access to BankAccountProtected's protected method because it is a derived class. This is a common pattern in polymorphism because derived classes often have a responsibility to call virtual base class methods to ensure critical functionality has the opportunity to execute. You would consult the method documentation to see if this was necessary. Without a protected access modifier, your only option would have been to make the base class method public; which, as explained earlier, is dangerous.

To use the code from Listings 19-3, 19-4, and 19-5, you can implement the following code:

BankAccountProtected[] bankAccts = new BankAccountProtected[2];
bankAccts[0] = new SavingsAccount();
bankAccts[1] = new CheckingAccount();

foreach (BankAccountProtected acct in bankAccts)
{
// call public method, which invokes protected virtual methods
acct.CloseAccount();
}

Since both SavingsAccount and CheckingAccount derive from BankAccountProtected, you can assign them to the bankAccts array. They both override the protected virtual methods of BankAccountProtected, so it is the SavingsAccount and CheckingAccount methods that are called when CloseAccount in BankAccountProtected executes. Remember that the only reason the methods of SavingsAccount and CheckingAccount can call their virtual base class methods, as in the case of DeleteAccountFromDB, is because the virtual base class methods are marked with the protected access modifier.
A Quick Word on internal and protected internal Access Modifiers

In practice, most of the code you write will involve the public, private, and protected access modifiers. However, there are two more access modifiers that you can use in more sophisticated scenarios: internal and protected internal.

You would use internal whenever you created a separate class library and you don't want any code outside of the library to access the code with internal access. The protected internal is a combination of the two access modifiers it is named after, which means either protected or internal.
Access Modifiers for Types

So far, the discussion of access modifiers has only applied to the members of types. However, the rules are different for the types themselves. When talking about types, I'm referring to all of the C# types, including classes, structs, interfaces, delegates, and enums. Nested types, such as a class defined within the scope of a class, are considered type members and fall under the same access rules as other type members.

Types can have only two access modifiers: public or internal. The default, if you don't specify the access modifier, is internal. Looking at all of the classes used in this lesson, you can see that they are internal because they don't have an access modifier. You can explicitly specify internal like this:

internal class InternalInterestCalculator
{
// members go here
}

Perhaps the InternalInterestCalculator, shown above, has special business rules that you don't want other code to use. Now, it is in a class library of its own and can only be accessed by other code inside of that same class library (DLL).

Note: To be more specific, internal means that only code in the same assembly can access code marked as internal. However, discussing the definition of an assembly is outside the scope of this lesson, so I am simplifying the terminology.

If you declared a class inside of a class library that you wanted other code to use, you would give it a public access modifier. The following code shows an example of applying the public access modifier to a type:

public class BankAccountExternal
{
// members go here
}

Clearly, a bank account is something you would want to access from outside of a class library. Therefore, it only makes sense to give it a public access modifier as shown in the BankAccountExternal class above.

Author: ketan Italiya24 Sep 2013 Member Level: Gold   Points : 10

Encapsulation, in the context of C#, refers to an object's ability to hide data and behavior that are not necessary to its user. Encapsulation enables a group of properties, methods and other members to be considered a single unit or object.

The following are the benefits of encapsulation:

Protection of data from accidental corruption
Specification of the accessibility of each of the members of a class to the code outside the class
Flexibility and extensibility of the code and reduction in complexity
Lower coupling between objects and hence improvement in code maintainability

Encapsulation is used to restrict access to the members of a class so as to prevent the user of a given class from manipulating objects in ways that are not intended by the designer. While encapsulation hides the internal implementation of the functionalists of class without affecting the overall functioning of the system, it allows the class to service a request for functionality and add or modify its internal structure (data or methods) to suit changing requirements.

Encapsulation is also known as information hiding.



Encapsulation in C# is implemented with different levels of access to object data that can be specified using the following access modifiers:

Public: Access to all code in the program
Private: Access to only members of the same class
Protected: Access to members of same class and its derived classes
Internal: Access to current assembly
Protected Internal: Access to current assembly and types derived from containing class

Encapsulation can be illustrated with an example of an Employee object that stores details of that object. By using encapsulation, the Employee object can expose the data (like Name, EmployeeID, etc.) and methods (like GetSalary) necessary for using the object, while hiding its irrelevant fields and methods from other objects. It's easy to see a situation in which all users could access basic information about an employee while restricting salary information.

C# allows encapsulation of data through the use of accessors (to get data) and mutators (to modify data), which help in manipulating private data indirectly without making it public. Properties are an alternate mechanism for private data to be encapsulated in a C# object and accessed in either read-only mode or in read-write mode. Unlike the accessor and mutator, a property provides a single point of access to an object's "set" and "get" values



  • Do not include your name, "with regards" etc in the comment. Write detailed comment, relevant to the topic.
  • No HTML formatting and links to other web sites are allowed.
  • This is a strictly moderated site. Absolutely no spam allowed.
  • Name:
    Email: