Lesson 1
Introduction to Encapsulation in Java
Introduction

Welcome! Today's subject is Encapsulation, a cornerstone of Object-Oriented Programming (OOP). Encapsulation bundles data and the operations that we perform on them into one unit, namely, an object. It guards data against unwanted alterations, ensuring the creation of robust and maintainable software.

Prepare yourself for an exciting journey as we delve into how encapsulation works in Java and explore the vital role it plays in data privacy.

Unraveling Encapsulation

Starting with the basics, encapsulation is similar to packing data and the methods that modify this data into a single compartment known as a class. It safeguards the data in an object from external interference.

To illustrate, consider a Java class representing a bank account. Without encapsulation, the account balance could be directly altered. With encapsulation, however, the balance can only change through specified methods, like depositing or withdrawing.

Java
1public class BankAccount { 2 public double balance; // no encapsulation 3 4 // Method to withdraw 5 public void withdraw(double amount) { 6 this.balance -= amount; 7 } 8 9 // Method to deposit 10 public void deposit(double amount) { 11 this.balance += amount; 12 } 13} 14 15public class Main { 16 public static void main(String[] args) { 17 BankAccount account = new BankAccount(); 18 account.balance += 1000; // directly accessing the balance 19 } 20}
Encapsulation: Guardian of Data Privacy

Encapsulation restricts direct access to an object's data and prevents unwanted data alteration. This principle is comparable to window blinds, allowing you to look out while preventing others from peeping in.

In Java, encapsulation pertains to private and public attributes, which are integral to data privacy. Private attributes, indicated by the private keyword, require caution while being manipulated.

To illustrate, let's consider a Java class named Person, which includes a private attribute name.

Java
1public class Person { 2 // Private attribute 3 private String name; 4 5 // Constructor 6 public Person(String name) { 7 this.name = name; 8 } 9 10 // Accessor method 11 public String getName() { 12 return this.name; 13 } 14 15 public static void main(String[] args) { 16 Person person = new Person("Alice"); 17 System.out.println(person.getName()); // Accessing private attribute via accessor method. Output: Alice 18 // The following line would cause an error due to private access: 19 // System.out.println(person.name); 20 } 21}

In this example, name is private, and getName() enables us to access name. However, we don't provide a method to change the name, preventing alterations.

In Java, all class members are public by default only within the same package. To designate an attribute as private, we use the private keyword.

Getter and Setter Methods in Encapsulation

Within encapsulation, Java uses getter and setter methods to access or modify private attributes. In a class, the getter method retrieves the attribute value, and the setter method alters it. Let's illustrate this.

Java
1public class Dog { 2 // Private attribute 3 private String name; 4 5 // Constructor 6 public Dog(String name) { 7 this.name = name; 8 } 9 10 // Setter method 11 public void setName(String name) { 12 this.name = name; 13 } 14 15 // Getter method 16 public String getName() { 17 return this.name; 18 } 19 20 public static void main(String[] args) { 21 Dog myDog = new Dog("Max"); 22 myDog.setName("Buddy"); 23 System.out.println(myDog.getName()); // Output: Buddy 24 } 25}

Here, setName() and getName() serve as the setter and getter methods, respectively, for the private attribute name.

Practical Application and Summary

Let's apply the principle of encapsulation to our BankAccount class, which includes private attributes like account number and balance, along with public methods for withdrawals, deposits, and balance checks.

Java
1public class BankAccount { 2 // Private attributes 3 private int accountNo; 4 private double balance; 5 6 // Constructor 7 public BankAccount(int accountNo, double balance) { 8 this.accountNo = accountNo; 9 this.balance = balance; 10 } 11 12 // Method to withdraw money 13 public void withdraw(double amount) { 14 if (amount > 0 && amount <= balance) { 15 this.balance -= amount; 16 } else { 17 System.out.println("Invalid amount or insufficient balance."); 18 } 19 } 20 21 // Method to deposit money 22 public void deposit(double amount) { 23 if (amount > 0) { 24 this.balance += amount; 25 } else { 26 System.out.println("Invalid deposit amount."); 27 } 28 } 29 30 // Method to check balance 31 public double checkBalance() { 32 return this.balance; 33 } 34 35 public static void main(String[] args) { 36 BankAccount account = new BankAccount(1, 500.0); 37 account.withdraw(100); 38 account.deposit(50); 39 System.out.println(account.checkBalance()); // Prints: 450.0 40 } 41}

In the above code, the BankAccount class encapsulates account details that we would like to be hidden from the outer scope, and the public methods manipulate the balance in a controlled way. This way, we limit the potential interaction with the account's balance and other private information, improving security.

Hands-on Exercise and Practice

Admirable! Now it's your turn to apply what you've learned by practicing encapsulation in Java. Remember, practice enhances your comprehension. Enjoy coding!

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