What is Encapsulation?
Encapsulation is one of the core principles of Object-Oriented Programming (OOP).
It involves bundling data (properties) and methods that operate on that data within a single unit (a class).
The primary goal is to protect the internal state of an object from unauthorized access or modification.
Benefits of Encapsulation
Data Protection: Protects internal data from accidental or unauthorized modification.
Code Maintainability: Makes it easier to modify the internal implementation of a class without affecting other parts of the code.
Increased Flexibility: Allows you to change the internal representation of data without impacting how other parts of the code interact with the class.
In Summary
Encapsulation is a crucial concept in OOP that promotes data security, code modularity, and maintainability. By using private fields and providing controlled access through getters and setters, you can create robust and flexible classes in Dart.
class Person
{
String _name; // Private field
Person(String name)
{
_name = name;
}
String get name => _name;
set name(String newName)
{
_name = newName;
}
}
void main()
{
Person person = Person('John Doe');
print('Name: ${person.name}');
person.name = 'Jane Doe';
print('Updated Name: ${person.name}');
}
Private Field:
_name is a private field within the Person class.
The underscore (_) before the name indicates that it's a private member, accessible only within the class itself.
Getter and Setter:
The get name and set name methods provide controlled access to the _name field.
get name allows you to read the value of the _name field.
set name allows you to modify the value of the _name field.
Object Interaction:
In the main function:
You can access and modify the name property using the getter and setter, even though the _name field is private.
This ensures that the _name field is not directly manipulated from outside the class, maintaining data integrity.
Here are 10 examples demonstrating encapsulation in Dart. In Dart, encapsulation is typically achieved by using private variables (prefixed with an underscore _) and providing public methods (getters, setters, and methods) to access or modify these variables.
Encapsulate data in a class with private variables and provide public getters and setters.
class Person
{
String _name;
int _age;
Person(this._name, this._age);
String get name => _name;
set name(String name) => _name = name;
int get age => _age;
set age(int age) => _age = age;
}
void main()
{
Person person = Person("Alice", 25);
print("Name: ${person.name}, Age: ${person.age}");
person.name = "Bob";
person.age = 30;
print("Updated Name: ${person.name}, Age: ${person.age}");
}
Use encapsulation to add validation logic within setters.
class BankAccount {
double _balance = 0.0;
double get balance => _balance;
void deposit(double amount) {
if (amount > 0) {
_balance += amount;
print("Deposited: \$${amount}");
} else {
print("Deposit amount must be positive.");
}
}
void withdraw(double amount) {
if (amount > 0 && amount <= _balance) {
_balance -= amount;
print("Withdrew: \$${amount}");
} else {
print("Insufficient funds or invalid amount.");
}
}
}
void main() {
BankAccount account = BankAccount();
account.deposit(500);
account.withdraw(100);
print("Balance: \$${account.balance}");
}
Using encapsulation to make a property read-only.
class Product {
final String _productName;
final double _price;
Product(this._productName, this._price);
String get productName => _productName;
double get price => _price;
}
void main() {
Product product = Product("Laptop", 1200.0);
print("Product: ${product.productName}, Price: \$${product.price}");
}
Encapsulation example with calculated properties.
class Rectangle
{
double _width;
double _height;
Rectangle(this._width, this._height);
double get area => _width * _height;
double get perimeter => 2 * (_width + _height);
}
void main()
{
Rectangle rect = Rectangle(5, 10);
print("Area: ${rect.area}");
print("Perimeter: ${rect.perimeter}");
}
A class that uses private methods to handle internal logic.
class Temperature {
double _celsius;
Temperature(this._celsius);
double get fahrenheit => _toFahrenheit(_celsius);
double _toFahrenheit(double celsius) => celsius * 9 / 5 + 32;
}
void main() {
Temperature temp = Temperature(25);
print("Temperature in Fahrenheit: ${temp.fahrenheit}");
}
Using encapsulation to initialize private variables through different constructors.
class Student {
String _name;
int _age;
Student(this._name, this._age);
Student.fromHighSchool() : _name = "High School Student", _age = 16;
Student.fromUniversity() : _name = "University Student", _age = 20;
String get name => _name;
int get age => _age;
}
void main() {
Student highSchoolStudent = Student.fromHighSchool();
Student universityStudent = Student.fromUniversity();
print("${highSchoolStudent.name}, Age: ${highSchoolStudent.age}");
print("${universityStudent.name}, Age: ${universityStudent.age}");
}
Using encapsulation to create immutable objects (properties that can't be changed after initialization).
class Car {
final String _brand;
final String _model;
final int _year;
Car(this._brand, this._model, this._year);
String get brand => _brand;
String get model => _model;
int get year => _year;
}
void main() {
Car car = Car("Toyota", "Corolla", 2022);
print("Car: ${car.brand} ${car.model}, Year: ${car.year}");
}
Encapsulate sensitive data with getters only, making the balance read-only.
class BankAccount {
double _balance = 1000.0;
double get balance => _balance;
void deposit(double amount) {
if (amount > 0) _balance += amount;
}
void withdraw(double amount) {
if (amount <= _balance) _balance -= amount;
}
}
void main() {
BankAccount account = BankAccount();
account.deposit(200);
account.withdraw(50);
print("Current balance: ${account.balance}");
}
A class that uses encapsulation to calculate a bonus based on salary.
class Employee {
String _name;
double _salary;
Employee(this._name, this._salary);
String get name => _name;
double get salary => _salary;
double get performanceBonus => _salary * 0.10; // 10% of salary
}
void main() {
Employee emp = Employee("Alice", 5000);
print("Employee: ${emp.name}, Salary: \$${emp.salary}");
print("Performance Bonus: \$${emp.performanceBonus}");
}
A library class using encapsulation to manage book borrowing.
class Library {
int _totalBooks;
int _borrowedBooks = 0;
Library(this._totalBooks);
int get availableBooks => _totalBooks - _borrowedBooks;
void borrowBook() {
if (_borrowedBooks < _totalBooks) {
_borrowedBooks++;
print("Book borrowed. Remaining books: $availableBooks");
} else {
print("No books available to borrow.");
}
}
void returnBook() {
if (_borrowedBooks > 0) {
_borrowedBooks--;
print("Book returned. Remaining books: $availableBooks");
}
}
}
void main() {
Library library = Library(5);
library.borrowBook();
library.borrowBook();
library.returnBook();
print("Total available books: ${library.availableBooks}");
}