[Java] Các mức truy cập trong java – Modifier in Java
Để bảo vệ dữ liệu tránh bị truy nhập tự do từ bên ngoài, lập trình hướng đối tượng sử dụng các từ khoá quy định phạm vi truy nhập các thuộc tính và phương thức của lớp. Java sử dụng một số bổ ngữ sau để kiểm soát việc truy nhập các thành phần của đối tượng :
- public: Thành phần công khai, truy nhập tự do từ bên ngoài.
- protected: Thành phần được bảo vệ, được hạn chế truy nhập.
- mặc định (không viết gì): Truy nhập trong nội bộ gói.
- private: Truy nhập trong nội bộ lớp.
1. Các thành phần public
Thành phần public là khu vực mà Lớp có thể chia sẻ với tất cả các chương trình và đối tượng bên ngoài. Thành phần public có thể được truy nhập từ bên trong lẫn bên ngoài lớp:
Ví dụ: ta có cấu trúc 2 gói như sau:
Trong đó nội dung các file của chúng ta như sau:
* file ClassA1.java nằm trong gói GoiA có các thành phần (biến varA1 và phương thức methodA1) là công khai (public):
package GoiA; // goi ten la GoiA public class ClassA1 { public int varA1 = 5; // bien cong khai ten la varA public void methodA1(){ // phuong thuc cong khai methodA1 System.out.println("methodA1 trong ClassA1 la public"); } }
* file ClassA2.java nằm trong gói GoiA gồm 1 phương thức methodA2 sử dụng được các thành phần của ClassA1.
package GoiA; // goi GoiA public class ClassA2 { // ClassA2 su dung bien va phuong thuc cua ClassA1 void methodA2(){ // phuong thuc methodA2 goi cac thanh phan cua ClassA1 ClassA1 a1 = new ClassA1(); // tao doi tuong a1 thuoc lop ClassA1 a1.methodA1(); // goi phuong thuc methodA1 System.out.println("Bien varA1 = " + a1.varA1); // in bien varA1 } }
* file ClassA3.java cũng nằm trong GoiA kế thừa và sử dụng được các thành phần của ClassA1
package GoiA; public class ClassA3 extends ClassA1{ // ClassA3 ke thua ClassA1 void methodA3(){ // phuong thuc methodA3 goi methodA1() methodA1(); } }
Chuyển sang gói GoiB ta có 2 file:
* file ClassB1.java cũng gọi các thành phần của ClassA1 giống như file ClassA2 tuy nhiên do ClassB1 nằm khác gói với ClassA1 nên chúng ta cần import nó.
package GoiB; import GoiA.ClassA1; // import ClassA1 de su dung public class ClassB1 { void methodB1(){ // phuong thuc methodB1 goi cac thanh phan cua ClassA1 ClassA1 a1 = new ClassA1(); // tao doi tuong a1 thuoc lop ClassA1 a1.methodA1(); // goi phuong thuc methodA1 System.out.println("Bien varA1 = " + a1.varA1); // in bien varA1 } }
* file ClassB2.java cũng kế thừa được ClassA1 giống như ClassA3 kế thừa ClassA1 nhưng cần phải import ClassA1 vào.
package GoiB; import GoiA.ClassA1; public class ClassB2 extends ClassA1{ // ClassB2 ke thua ClassA1 void methodB2(){ // phuong thuc methodB2 goi methodA1() methodA1(); } }
Như vậy chúng ta có thể thấy được tính công khai ở mọi nơi của ClassA1 khi ta dùng bổ ngữ public.
Ta có thể rút ra nhận xét nhanh bằng hình ảnh minh họa sau:
2. Các thành phần protected
Tất cả các lớp trong gói chứa nó và tất cả các lớp kế thừa nó (bao gồm cả các lớp kế thừa từ các gói khác) sẽ truy cập được tới nó.
Cũng với VD như trên, chúng ta có 2 gói là GoiA và GoiB cùng với các class đó, chỉ thay đổi ClassA1 với các thành phần protected như sau (các ClassA2, ClassA3, ClassB1, ClassB2 vẫn giữ nguyên):
*flie ClassA1.java
package GoiA; // goi ten la GoiA public class ClassA1 { protected int varA1 = 5; // bien protected ten la varA protected void methodA1(){ // phuong thuc protected methodA1 System.out.println("methodA1 trong ClassA1 la public"); } }
Khi đó các lớp ClassA2, ClassA3 vẫn truy cập được vào các thành phần của ClassA1 vì nó nằm cùng gòi GoiA với ClassA1, ClassB2 cũng truy cập được vì tuy khác gói nhưng nó kế thừa ClassA1. Tuy nhiên ClassB1 thì không thể truy nhập được.
*flie ClassB1.java
package GoiB; import GoiA.ClassA1; // import ClassA1 de su dung public class ClassB1 { void methodB1(){ // phuong thuc methodB1 goi cac thanh phan cua ClassA1 ClassA1 a1 = new ClassA1(); a1.methodA1(); // loi truy nhap System.out.println("Bien varA1 = " + a1.varA1); // loi truy nhap } }
ClassB1 bị lỗi
Nhận xét:
3. Các thành phần default
Các thành phần mặc định (không khai báo gì) thì chỉ cho phép các lớp trong cùng 1 gói truy nhập tới (kể cả khi kế thừa). Mọi sự truy nhập hoặc kế thừa từ các gói khác đều không được.
Tương tự, với ví dụ trên ta để các thành phẩn của ClassA1 là default, khi đó ClassB1 và ClassB2 đều bị lỗi vì nó không nằm trong cùng gói với ClassA1.
* file ClassA1.java
package GoiA; // goi ten la GoiA public class ClassA1 { int varA1 = 5; // bien mac dinh ten la varA void methodA1(){ // phuong thuc mac dinh methodA1 System.out.println("methodA1 trong ClassA1 la public"); } }
*flie ClassB1.java
package GoiB; import GoiA.ClassA1; // import ClassA1 de su dung public class ClassB1 { void methodB1(){ // phuong thuc methodB1 goi cac thanh phan cua ClassA1 ClassA1 a1 = new ClassA1(); a1.methodA1(); // loi truy nhap System.out.println("Bien varA1 = " + a1.varA1); // loi truy nhap } }
*flie ClassB2.java
package GoiB; import GoiA.ClassA1; public class ClassB2 extends ClassA1{ // ClassB2 ke thua ClassA1 void methodB2(){ // phuong thuc methodB2 goi methodA1() methodA1(); // loi truy nhap } }
ClassB1, ClassB2 đều bị lỗi mặc dù ClassB2 chúng ta có thể khai báo là extends ClassA1 nhưng cũng không sử dụng được các thành phần của ClassA1.
Nhận xét:
4. Các thành phần private
Các thành phần riêng tư được bảo vệ chặt chẽ nhất, chỉ có các đối tượng trong cùng 1 lớp mới truy nhập được, mọi sự truy nhập hay kế thừa từ các lớp khác ngay cả khi các lớp đó trong cùng 1 gói cũng không truy nhập được.
*flie ClassA1.java
package GoiA; // goi ten la GoiA public class ClassA1 { private int varA1 = 5; // bien private ten la varA private void methodA1(){ // phuong thuc private methodA1 System.out.println("methodA1 trong ClassA1 la public"); } void methodA2(){ methodA1(); // goi phuong thuc methodA1 System.out.println("Bien varA1 = " + varA1); // in bien varA1 } }
Chúng ta thấy chỉ có phương thức methodA2() nằm cùng Class với các thành phần private của ClassA1 mới có thể truy nhập, ngay cả ClassA2, ClassA3 nằm cùng gói GoiA cũng không thể truy nhập.
Nhận xét:
Như vậy ta có thể thấy khả năng truy nhập của các thành phần public, protected, default, private giảm dần đồng nghĩa với khả năng bảo mật thông tin tăng dần. Ta có thể có một sự tổng kết nho nhỏ sau:
Bài viết có sự tham khảo của:
– Giáo trình lập trình hướng đối tượng Java – Đoàn Văn Ban
– Giáo trình lập trình hướng đối tượng Java – Trần Đình Quế
– naynhoanhthichem.blogspot.com
Và một số giáo trình, website khác.
Cám ơn bro đã có giải thích rất trực quan 🙂
Ghé thăm blog thường xuyên ^^
Cam on Nguyenvanquan7826 rat hay, truoc den gio minh van thay mung lung cac thuoc tinh nay. Nay doc bai viet nay thi hieu tuyet doi 100%. Hay…Qua ro rang.
cách giải thích của anh rất dễ hiểu
Cảm ơn bạn.
Cám ơn bạn rất nhiều. Bài viết cực kỳ dễ hiểu.Thậm chí chỉ cần xem hình ảnh minh họa dưới dòng “Nhận xét:” cũng đã hiểu hết và nhớ dai rồi.
Cảm ơn bạn. Hãy giới thiệu cho bạn bè nhé.
Bạn cho mình hỏi không gọi trực tiếp hàm từ lớp kế thừa đc à bạn. Ví dụ:package GoiA;
public class ClassA3 extends ClassA1{
void methodA3(){
methodA1();
}
}
Ở class trên sao mình không gọi luôn methodA1(); mà lại cần nó trong một method (ở đây là mehodA3 ) khác vậy bạn?
Gọi được đó bạn… Ý mình là chúng ta có thể gọi được các phương thức của lớp cha, tuy nhiên muốn gọi thì bạn cần cho nó vào 1 hàm hoặc phải dùng một đối tượng để gọi.
cho em hỏi phương thức A trong package 1 em để chế độ public . vậy ở package 2 em có gọi phương thức A được không ạ
Có chứ bạn.
Cảm ơn anh rất nhiều. Bài viết rất rõ ràng, dễ hiểu. Chúc anh đạt được nhiều thành công và có nhiều bài viết hay như thế này nữa 🙂
Cảm ơn bạn.
Bài viết của anh rất hay!
Cảm ơn bạn
Bài viết rất hay và chi tiết. Cảm ơn bạn!
Cảm ơn bạn, hãy chia sẻ cho bạn bè nhé
cảm ơn bạn rất nhiều , page bạn giải thích còn dễ hiểu hơn là trên lớp dạy đấy
Cảm ơn bạn 🙂 Chia sẻ cho bạn bè nhé.
bài này hay quá anh ơi :D,anh cho em xin link bài giảng try catch luôn nha,em hơi thắc mắc khi nghe giáo viên giảng.Thầy cô nói try catch khi mình ko chắc code đúng nên dùng,mà em nghĩ nếu biết nó ko đúng thì sửa lại luôn chứ :))
hay hiểu 100% cảm ơn bạn
Chia sẻ cho bạn bè và ghé blog thường xuyên nhé bạn.