C# > Object-Oriented Programming (OOP) > Classes and Objects > Access Modifiers (public, private, protected, internal)
Access Modifiers in C#
This snippet demonstrates the use of access modifiers (public
, private
, protected
, and internal
) in C# classes. Access modifiers control the visibility and accessibility of class members from different parts of the code.
Code Snippet
This code defines a BankAccount
class with members demonstrating different access modifiers. AccountHolderName
is public
, making it accessible from anywhere. _balance
is private
, so it's only accessible within the BankAccount
class. TransactionCount
is protected
, making it accessible within the BankAccount
class and any derived classes like SavingsAccount
. AccountNumber
is internal
, so it is accessible within the same assembly (project). The SavingsAccount
class inherits from BankAccount
and demonstrates accessing the protected
member TransactionCount
. The Main
method creates instances of both classes and demonstrates how the access modifiers restrict or allow access to different members.
using System;
namespace AccessModifierExample
{
public class BankAccount
{
// Public member: Accessible from anywhere
public string AccountHolderName { get; set; }
// Private member: Only accessible within the class
private decimal _balance;
// Protected member: Accessible within the class and derived classes
protected int TransactionCount { get; set; }
// Internal member: Accessible within the same assembly
internal string AccountNumber { get; set; }
public BankAccount(string accountHolderName, string accountNumber, decimal initialBalance)
{
AccountHolderName = accountHolderName;
AccountNumber = accountNumber;
_balance = initialBalance;
TransactionCount = 0;
}
// Public method to deposit money
public void Deposit(decimal amount)
{
if (amount > 0)
{
_balance += amount;
TransactionCount++;
Console.WriteLine($"Deposited {amount}. New balance: {_balance}");
}
else
{
Console.WriteLine("Invalid deposit amount.");
}
}
// Public method to withdraw money
public void Withdraw(decimal amount)
{
if (amount > 0 && _balance >= amount)
{
_balance -= amount;
TransactionCount++;
Console.WriteLine($"Withdrawn {amount}. New balance: {_balance}");
}
else
{
Console.WriteLine("Insufficient funds or invalid withdrawal amount.");
}
}
// Private method (only accessible within this class)
private decimal GetBalance()
{
return _balance;
}
// Protected method (accessible within this class and derived classes)
protected void DisplayTransactionCount()
{
Console.WriteLine($"Transaction Count: {TransactionCount}");
}
// Internal method (accessible within the same assembly)
internal void SetAccountNumber(string newAccountNumber)
{
AccountNumber = newAccountNumber;
}
}
// Derived class demonstrating protected access
public class SavingsAccount : BankAccount
{
public SavingsAccount(string accountHolderName, string accountNumber, decimal initialBalance) : base(accountHolderName, accountNumber, initialBalance)
{
}
public void DisplayTransactionHistory()
{
// Accessing protected member TransactionCount from the base class
Console.WriteLine("Displaying transaction history...");
DisplayTransactionCount(); // Accessing protected method
}
}
class Program
{
static void Main(string[] args)
{
// Creating a BankAccount object
BankAccount account = new BankAccount("John Doe", "12345", 1000);
// Accessing public members
Console.WriteLine($"Account Holder: {account.AccountHolderName}");
account.Deposit(500);
account.Withdraw(200);
// The following line would cause a compilation error because _balance is private
// Console.WriteLine($"Balance: {account._balance}");
//Creating a SavingsAccount object
SavingsAccount savingsAccount = new SavingsAccount("Jane Doe", "67890", 500);
savingsAccount.DisplayTransactionHistory();
// Accessing internal member within the same assembly
account.SetAccountNumber("54321");
Console.WriteLine($"Account Number Updated: {account.AccountNumber}");
Console.ReadKey();
}
}
}
Concepts Behind the Snippet
Access modifiers are a fundamental part of object-oriented programming, providing encapsulation and information hiding. They allow you to control the visibility of class members, preventing unintended modification or access from outside the class. This promotes code maintainability, security, and reduces the risk of errors. Each access modifier serves a specific purpose: public
provides unrestricted access, private
restricts access to within the class, protected
allows access within the class and derived classes, and internal
restricts access to within the same assembly.
Real-Life Use Case
Imagine a system for managing employee data. Employee salaries should be private
and only accessible through authorized methods like CalculatePaycheck
. Employee names, addresses, and other general information could be public
for easy access. A manager's access level to certain employee information, like performance reviews, could be protected
(accessible only to the manager class derived from employee). Components used only within the employee management module, like database connection strings, might be internal
.
Best Practices
private
and only increase visibility when necessary.public
.public
members.
Interview Tip
Be prepared to explain the differences between protected
and internal
access modifiers. Also, understand the concept of assembly-level access and how internal
members contribute to modularity.
When to Use Them
public
when a member needs to be accessible from anywhere.private
when a member should only be accessible within the class itself.protected
when a member should be accessible within the class and any derived classes.internal
when a member should only be accessible within the same assembly (project).
Memory Footprint
Access modifiers don't directly affect the memory footprint of an object. They only control visibility and access. The size of an object is determined by its data members, regardless of their access modifiers.
Alternatives
While access modifiers are the primary mechanism for controlling visibility, other techniques like interfaces and abstract classes can also contribute to encapsulation and information hiding. For example, an interface can define a public contract while hiding the specific implementation details within a class.
Pros
Cons
private
can lead to excessively complex code.
FAQ
-
What is the default access modifier if I don't specify one?
The default access modifier for class members in C# isprivate
. -
Can a
private
member be accessed from a derived class?
No,private
members are not accessible from derived classes. You need to useprotected
if you want derived classes to access a member. -
What is the difference between
internal
andprotected internal
?
internal
members are accessible within the same assembly.protected internal
members are accessible within the same assembly or from derived classes, even if they are in a different assembly.