Master Encapsulation in Java - Unlock the Power of Getters, Setters & this Keyword!
Table of contents
Introduction to Encapsulation
What is Encapsulation ?
Encapsulation is a way of keeping data safe inside a class. It means we hide the details of how something works and only allow access through special methods (getters and setters). This helps protect data from unwanted changes, makes the code easier to manage, and keeps everything organized.
Why is Encapsulation Important?
Encapsulation is important because it helps protect data and keeps a program organized. By making variables private, we prevent them from being changed directly from outside the class. Instead, we use getters and setters to control how data is accessed or modified. This reduces the risk of errors, makes debugging easier, and allows changes to be made without affecting other parts of the program.
as an example, imagine a Bank Account class. If the balance variable is public, anyone can change it freely, even setting a negative balance. With encapsulation, we make it private and allow updates only through a setBalance() method that checks if the value is valid.
let’s learn Encapsulation in Java
Let's look at an example scenario of a bank account and create a bankAccount class and try to print some data in the bankAccount class
class BankAccount{
private int bankBlance;
private String ownersName;
private int accountNumber = 741852;
}
public class Main {
public static void main(String[] args) {
BankAccount bankAccount= new BankAccount();
System.out.println(bankAccount.accountNumber);
}
}
Output = Main.java:6:43 java: accountNumber has private access in BankAccount
Why this happened ?
code will produce a compilation error because the accountNumber
variable is private in the BankAccount
class. Since private variables cannot be accessed directly from outside the class, the following line will cause an error:
Then how can we access the accountNumber?
That's where getters and setters come into play. We can use methods to set values for the private variables and use get methods to retrieve values from these variables. Here's how it works
public class Main {
public static void main(String[] args) {
BankAccount bankAccount= new BankAccount();
System.out.println("old Account Number "+ bankAccount.getAccountNumber());
bankAccount.setAccountNumber(1000);
System.out.println("New Account Number "+ bankAccount.getAccountNumber());
}
}
class BankAccount{
private int bankBlance;
private String ownersName;
private int accountNumber = 741852;
public int getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(int newAccountNumber) {
accountNumber = newAccountNumber;
}
}
Output =
old Account Number 741852
New Account Number 1000
As you can see, I can now access the accountNumber
variable inside BankAccount
using the public method getAccountNumber()
. I can also change its value to a new account number by passing data as a parameter to setAccountNumber(1000)
.
insted of typing all this getters and setters we can use out IDE code editors to auto genarate getters and setters for us this is how you can do it
No need to write getters and setters manually in a tedious way - use your IDE to generate them automatically.
step 1 - I use IntelliJ, and the process is similar for most other IDEs. Right-click on your class and find "Generate."
step 2- as below image show you can click on getters and setters option
step 3 - Now you can select the relevant variable that needs getters and setters, then click OK. All done!
Result
class BankAccount{ private int bankBlance; private String ownersName; private int accountNumber = 741852; public int getBankBlance() { return bankBlance; } public void setBankBlance(int bankBlance) { this.bankBlance = bankBlance; } public String getOwnersName() { return ownersName; } public void setOwnersName(String ownersName) { this.ownersName = ownersName; } public int getAccountNumber() { return accountNumber; } public void setAccountNumber(int accountNumber) { this.accountNumber = accountNumber; } }
What is this
key word ?
Instead of explaining the this
keyword, I'll show you a scenario of what happens if I stop using it and write the code above like this
public class Main {
public static void main(String[] args) {
BankAccount bankAccount= new BankAccount();
System.out.println("old Account Number "+ bankAccount.getAccountNumber());
bankAccount.setAccountNumber(1000);
System.out.println("New Account Number "+ bankAccount.getAccountNumber());
}
}
class BankAccount{
private int accountNumber = 741852;
public int getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(int accountNumber) {
accountNumber = accountNumber;
}
}
now no accountNumber = newAccountNumber
i am jsut assigning accountNumber = accountNumber if i run this code the answer will be like this
output =
old Account Number 741852
New Account Number 741852
Oh, why are the old and new values the same? What happened here?
The old and new account numbers are the same because the setAccountNumber()
method isn't actually changing the value. It's just assigning the accountNumber
to itself, using the parameter sent to the function, and the parameter itself gets updated. and naver change the value of private int accountNumber = 741852;
This is how this
key word used
By using the this
keyword, we explicitly indicate that this.accountNumber
refers to the instance variable of the BankAccount
class, distinguishing it from method parameters or local variables with the same name. This ensures clarity and prevents unintended variable shadowing, making the code more readable and maintainable.
public class Main {
public static void main(String[] args) {
BankAccount bankAccount= new BankAccount();
System.out.println("old Account Number "+ bankAccount.getAccountNumber());
bankAccount.setAccountNumber(1000,bankAccount);
System.out.println("New Account Number "+ bankAccount.getAccountNumber());
}
}
class BankAccount{
private int accountNumber = 741852;
public int getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(int accountNumber) {
this.accountNumber = accountNumber;
}
}