Giải pháp chuyển đổi số trọn gói cho doanh nghiệp Việt
Bài hôm nay chúng ta sẽ nói đến một vấn đề đã được hứa khá lâu, từ khi các bạn mới vừa làm quen với các thuộc tính và phương thức của lớp, đó là kiến thức về khả năng truy cập vào các thành phần của lớp. Vậy thì cái khả năng truy cập này là gì và chúng quan trọng như thế nào, mời các bạn cùng theo dõi bài học nhé.
Khả năng truy cập, hay còn gọi là access modifier, là các từ khóa được Java cung cấp sẵn. Và bạn, hay các lập trình viên khác sẽ sử dụng các định nghĩa của các từ khóa này, để thể hiện các quyền được truy cập vào các thành phần của lớp. Các thành phần của lớp ở đây mình muốn nhắc đến bao gồm các thuộc tính, các phương thức, và cả các constructor của một lớp.
Các từ khóa liên quan đến access modifier trong Java chính là: private, protected, public và default.
Chúng ta khoan hãy nói đến từng khả năng truy cập đã nêu trên, mà hãy điểm lại xem làm cách nào để khai báo một khả năng truy cập nhé.
Bạn hãy nhớ lại đi, trong các cú pháp liên quan đến việc khai báo các thành phần của lớp, mình đều có nêu cách khai báo khả năng truy cập này rồi đấy.
Chẳng hạn như khi khai báo thuộc tính của lớp này.
[khả_năng_truy_cập] kiểu_thuộc_tính tên_thuộc_tính [= giá_trị_ban_đầu];
Hay khi khai báo phương thức của lớp này.
[kả_năng_truy_cập] kiểu_trả_về tên_phương_thức () {
// Các dòng code
}
Hay khi khai báo một constructor này.
[khả_năng_truy_cập] tên_phương_thức () {
// Các dòng code
}
Vậy bạn có thể hiểu cách để định nghĩa một khả năng truy cập vào các thành phần lớp rồi đúng không nào. Dưới đây là một ví dụ đầy đủ cho việc khai báo các khả năng truy cập này ở lớp HinhTron.
Nào, giờ chúng ta sẽ đi qua từng khả năng truy cập xem chúng có ý nghĩa và lợi ích gì nhé.
Trước hết, mình xin tổng hợp các khả năng truy cập dựa trên một bảng dưới đây, để cho các bạn dễ nhớ. Bảng này chỉ đơn giản mang các giá trị “Có” nếu như định nghĩa này cho phép truy cập ở một phạm vi nào đó, và mang giá trị “Không” cho ý nghĩa ngược lại.
| Phạm vi | private | default | protected | public |
|---|---|---|---|---|
| Bên trong lớp | Có | Có | Có | Có |
| Ở lớp khác, nhưng trong cùng package | Không | Có | Có | Có |
| Ở lớp con, trong cùng package | Không | Có | Có | Có |
| Ở lớp con, khác package | Không | Không | Có | Có |
| Ở bất cứ lớp nào khác (không phải lớp con), khác package | Không | Không | Không | Có |
Giờ mình sẽ nói rõ hơn từng khả năng truy cập.
Nếu bạn chỉ định một thành phần nào đó (thuộc tính, phương thức hay constructor) của lớp là private, thì như bảng trên, bạn chỉ có thể truy xuất đến thành phần này bên trong lớp đó mà thôi.
Khả năng private này mang ý nghĩa bảo vệ các thành phần bên trong lớp, không cho các lớp bên ngoài có thể “nhìn thấy” (đọc và chỉnh sửa) được.
Bạn nên tập một thói quen, đó là luôn khai báo private cho các thuộc tính bên trong lớp. Với phương thức thì nếu bạn không chắc nó có được dùng ở đâu đó bên ngoài lớp này hay không, thì cứ chỉ định private luôn cho chắc cú.
Bài thực hành này mình tạo lớp HinhTron có khai báo các thành phần là private. Bạn có thể thấy các thành phần này khi dùng bên trong lớp HinhTron thì rất tốt, không bị báo lỗi từ hệ thống.
Vậy bạn có thể tự trắc nghiệm xem, với việc gọi đến các thành phần này của HinhTron từ main(), thì dòng code nào sau đây sẽ bị hệ thống báo lỗi nhé.
Kết quả dòng bị báo lỗi ở dưới đây.
Thực ra không có một kiểu định nghĩa khả năng default nào cả. default ở đây có nghĩa là bạn không định nghĩa khả năng truy cập gì hết, nó giống như các bài học mở đầu mà chúng ta đã làm quen, khi đó chúng ta tạm thời để trống các khai báo khả năng truy cập này.
Và với việc để trống khả năng truy cập cho các thành phần của lớp, thì bạn có thể thấy rằng, nếu bên trong lớp đó hoặc các lớp khác trong cùng package, sẽ có thể nhìn thấy và truy xuất đến các thành phần đó. Khả năng nhìn thấy và truy xuất chỉ bị chặn khi bạn gọi đến các thành phần này từ một lớp nằm ngoài package mà thôi.
Khả năng này nên ít được dùng hơn, vì bạn nên tập thói quen chỉ định khả năng truy cập một cách tường minh từ bây giờ.
Ở đây mình bỏ hết các khai báo khả năng truy cập cho các thành phần của lớp HinhTron.
Và tương tự, với các dòng code khai báo ở main() như sau, bạn đoán xem dòng nào sẽ bị lỗi nhé.
Kết quả dòng bị lỗi như sau.
Sở dĩ các dòng này báo lỗi, là vì chúng ở package main khác với package shapes của HinhTron. Bạn thử đưa chúng về cùng một package rồi kiểm chứng lại nhé.
Khả năng này mang ý nghĩa bảo vệ các thành phần của lớp cho các lớp con của nó dùng lại hoặc ghi đè. Do đó có thể hiểu, khả năng protected sẽ trao quyền sử dụng hoàn toàn tự do cho các lớp con, dù có ở cùng hay khác package. Khả năng này chỉ giới hạn với các lớp không phải lớp con của nó và nằm ngoài package mà thôi.
Lần này bạn hãy xem các khai báo protected cho các thành phần bên trong HinhTron như sau.
Và với code ở main(), bạn lại thử đoán xem dòng code nào bị báo lỗi.
Kết quả dòng bị lỗi như sau.
Phương thức tinhDienTich() rơi vào trường hợp “Không” duy nhất của protected. Bởi nó vừa gọi từ một lớp không có quan hệ kế thừa với HinhTron, và cũng nằm ngoài package so với HinhTron nữa.
Vẫn với code của Bài thực hành số 3, lần này mình khai báo thêm HinhTru kế thừa từ HinhTron, và main() như sau. Bạn xem có dòng nào báo lỗi không nhé.
Đây là kết quả các dòng báo lỗi.
Vì HinhTru kế thừa các phương thức từ cha và set lại khả năng truy cập là public.
Có lẽ không cần tốn nhiều giấy mực để nói về khả năng này. Nếu bạn chỉ định một thành phần trong lớp là public, thì coi như tất cả các lớp nào khác đều có thể truy xuất đến các thành phần này.
Chưa có câu hỏi nào cho bài này.