1. Tính đóng gói (encapsulation) trong Java là gì?
Tính đóng gói (encapsulation) là việc đóng gói các thuộc tính và phương thức bên trong lớp. Tức là thiết kế để các thuộc tính và phương thức thuộc về (bên trong) một lớp.
Với các access modifier, tính đóng gói sẽ có thể giúp ngăn chặn những lớp bên ngoài truy cập, thay đổi thuộc tính và phương thức của một lớp. Từ đó, giúp cho việc che giấu dữ liệu (data hiding).
class HinhChuNhat{
double chieudai;
double chieurong;
HinhChuNhat(double chieudai, double chieurong){
this.chieudai = chieudai;
this.chieurong = chieurong;
}
void tinhDientich(){
double dientich = chieudai*chieurong;
System.out.println("Dien tich hinh chu nhat = " + dientich);
}
}
public class Main {
public static void main(String args[]) {
HinhChuNhat hcn = new HinhChuNhat(7, 5);
hcn.tinhDientich();
}
}
Kết quả
Dien tich hinh chu nhat = 35.0
Lớp HinhChuNhat được tạo ra, mục đích chính của lớp này là tính diện tích. Để tính diện tích thì cần chiều dài và chiều rộng. Một hàm tinhDientich()
được dùng để tính diện tích và xuất ra giá trị diện tích tính được. Chúng ta có thể gộp các thuộc tính và phương thức vào trong một lớp HinhChuNhat. Đó là sự đóng gói (encapsulation).
2. Tại sao sử dụng tính đóng gói (encapsulation)
Trong Java, tính đóng gói (encapsulation) giúp chúng ta đóng gói các thuộc tính và phương thức liên quan với nhau trong một lớp. Nó cũng giúp chúng ta có thể thay đổi giá trị của các thuộc tính thông qua phương thức. Điều này làm cho code rõ ràng và dễ đọc hơn. Ví dụ, chúng ta có thể viết code như sau để tính diện tích các hình chữ nhật.
public class Main {
public static void main(String args[]) {
double chieudai1=7;
double chieurong1=5;
System.out.println("Dien tich hinh chu nhat = " + chieudai1*chieurong1);
double chieudai2=9;
double chieurong2=2;
System.out.println("Dien tich hinh chu nhat = " + chieudai2*chieurong2);
double chieudai3=8;
double chieurong3=7;
System.out.println("Dien tich hinh chu nhat = " + chieudai3*chieurong3);
}
}
Kết quả
Dien tich hinh chu nhat = 35.0
Dien tich hinh chu nhat = 18.0
Dien tich hinh chu nhat = 56.0
Chúng ta có thể sử dụng tính đóng gói để gộp các thuộc tính và phương thức của hình nhữ nhật thành 1 lớp. Sau đó, tạo các đối tượng hình chữ nhật để tính diện tích như sau:
class HinhChuNhat{
double chieudai;
double chieurong;
HinhChuNhat(double chieudai, double chieurong){
this.chieudai = chieudai;
this.chieurong = chieurong;
}
void tinhDientich(){
double dientich = chieudai*chieurong;
System.out.println("Dien tich hinh chu nhat = " + dientich);
}
}
public class Main {
public static void main(String args[]) {
HinhChuNhat hcn1 = new HinhChuNhat(7, 5);
hcn1.tinhDientich();
HinhChuNhat hcn2 = new HinhChuNhat(9, 2);
hcn2.tinhDientich();
HinhChuNhat hcn3 = new HinhChuNhat(8, 7);
hcn3.tinhDientich();
}
}
Kết quả
Dien tich hinh chu nhat = 35.0
Dien tich hinh chu nhat = 18.0
Dien tich hinh chu nhat = 56.0
Rõ ràng, kết quả của các cách code là như nhau. Nhưng với cách sử dụng tính đóng gói thì dễ đọc, dễ hiểu hơn. Và quan trọng là khi muốn tính diện tích của nhiều hình chữ nhật thì rõ ràng, dễ hiểu hơn thay vì phải khai báo nhiều biến chiều dài và chiều rộng.
Hơn nữa, nếu muốn thực hiện các thao tác khác trên hình chữ nhật như tính chu vi, thay đổi chiều dài, chiều rộng,… chỉ cần thêm phương thức xử lý vào lớp.
3. Cơ chế che giấu dữ liệu (data hiding) của lớp trong Java
Data hiding là một cách hạn chế quyền truy cập các thuộc tính dữ liệu của lớp bằng cách hạn chế phạm vi truy cập của chúng với các access modifier.
Với chỉ định truy cập là private thì các thuộc tính dữ liệu chỉ có thể truy cập từ các phương thức bên trong lớp nhằm bảo vệ dữ liệu. Các đối tượng khác muốn truy nhập vào dữ liệu riêng tư này phải thông qua các phương thức public.
Đó là các phương thức accessor (getter) trả về giá trị hiện tại của một thuộc tính và mutator (setter) sẽ thay đổi giá trị của một thuộc tính. Định dạng tên của các phương thức này thường là getX và setX với X là tên thuộc tính.
class Person {
//thuộc tính private
private int age;
//phương thức getter
public int getAge() {
return age;
}
//phương thức setter
public void setAge(int age) {
this.age = age;
}
}
class Main {
public static void main(String[] args) {
Person p1 = new Person();
//thay đổi thuộc tính age với setter
p1.setAge(24);
//lấy giá trị thuộc tính age với getter
System.out.println("My age is " + p1.getAge());
}
}
Kết quả
My age is 24
Trong ví dụ trên, thuộc tính age của lớp Person được khai báo là private và không thể truy cập bên ngoài lớp Person. Để truy cập age bên ngoài lớp Person, chúng ta sử dụng phương thức public getAge()
và setAge()
. Thuộc tính age được khai báo private để hạn chế truy cập từ bên ngoài lớp. Đó là data hiding.