- vừa được xem lúc

[Object-Oriented + Java] Bài viết #3 - Package & Access Modifiers

0 0 23

Người đăng: Semi Dev

Theo Viblo Asia

Bây giờ thì chúng ta đã có thể có rất nhiều các class có liên quan với nhau theo mô hình kế thừa hoặc tính năng bổ trợ. Lúc này mối quan tâm tiếp theo là câu chuyện sắp xếp và quản lý các tệp mã nguồn .java.

Package

Khái niệm package trong Java được hiểu là một tên miền namespace, nơi mà chúng ta có thể sử dụng các tên class mà không phải lo chuyện trùng lặp với các class khác ở bên ngoài không gian đó.

Và bởi vì Java quy định mỗi tệp mã nguồn .java sẽ phải được đặt tên trùng với class định nghĩa trong code của tệp đó, vì vậy nên chúng ta cũng có thể hiểu rằng một package là một thư mục chứa các tệp code. Chúng ta hiển nhiên không thể có nhiều tệp code mã nguồn .java trùng tên trong cùng một thư mục được, nhưng lại chắc chắn có thể sử dụng lại các tên class trong các thư mục khác nhau.

Ví dụ:

/learn-java
├── app
│ ├── Main.java
│ ├── data
│ │ └── Person.java
│ └── delegate
│ └── Person.java
└── src.txt
package app.data; // -- package declaration class Person { String name = ""; int age = 0; Person (String $name, int $age) { this.name = $name; this.age = $age; } } // -- end class

Mặc định thì các class sẽ chỉ khả dụng trong không gian của package chứa chúng, và thêm vào đó thì Java xem các package là đồng đẳng và không liên quan tới nhau; Vì vậy nên mặc dù package app về mặt quản lý thư mục thì đúng là có chứa hai package con là app.dataapp.delegate, nhưng trong logic vận hành thì code của Main.java sẽ phải tham chiếu tới các class khác bằng cách chỉ rõ tên miền đang chứa hoặc thực hiện thao tác import giống như chúng ta đã sử dụng package java.io trước đó.

Ví dụ:

app.data.Person $me = new app.data.Person ("Semi Dev_", 1001);

Hoặc:

package app; import app.data.Person;
import java.io.*; class Main { public static void main (String[] $args) { Person $me = new Person ("Semi Dev_", 1001); System.out.println ($me.name); } } // -- end class

Tuy nhiên, để các thao tác tham chiếu đã nói ở trên có thể hoạt động được thì chúng ta còn phải xem xét thêm một yếu tố nữa, đó là tính năng đóng gói Encapsulation và mức độ hiển thị của các thành phần package membersclass members đối với code tham chiếu.

> javac @src.txt
./app/Main.java:3: error: Person is not public in app.data; cannot be accessed from outside package
import app.data.Person; ^
./app/Main.java:9: error: Person is not public in app.data; cannot be accessed from outside package Person $me = new Person ("Semi Dev_", 1001); ^

Access Modifiers

Java có cung cấp một bộ các từ khóa tùy chỉnh mức độ hiển thị để thể hiện chức năng đóng gói Encapsulation. Các từ khóa này được sử dụng bằng cách gắn làm tiền tố ở phía trước các thành phần package membersclass members.

Các class và các interface mà chúng ta sẽ nói đến ở bài viết sau - được xem là các package members và được áp dụng hai mức độ hiển thị đối với code tham chiếu là:

  • default - chỉ khả dụng đối với không gian bên trong packgage. Đây là cấp độ mặc định và chúng ta có thể viết từ khóa default ở phía trước từ khóa class hoặc interface - hoặc không viết cũng được.
  • public - khả dụng đối với cả code tham chiếu từ bên ngoài package.

Đối với các class members thì chúng ta lại có thêm hai mức độ hiển thị nữa:

  • private - chỉ khả dụng với code định nghĩa bên trong nội bộ của class đó.
  • default - chỉ khả dụng đối với code tham chiếu bên trong packgage.
  • protected - khả dụng với code tham chiếu bên trong package và các class kế thừa ở bên ngoài package.
  • public - khả dụng đối với code tham chiếu từ bất kỳ đâu.

Như vậy, để code ví dụ ở phần trước có thể vận hành được thì chúng ta cần thêm từ khóa public vào phía trước từ khóa class để bắt đầu định nghĩa class Person và các thành phần bên trong class Person:

package app.data; public class Person { public String name = ""; public int age = 0; public Person (String $name, int $age) { this.name = $name; this.age = $age; } } // -- end class

Extends Visibility

Khi nhắc tới các từ khóa quy định mức hiển thị access modifiers thì chúng ta còn một trường hợp phải lưu ý đó là thao tác override khi viết các class kế thừa.

Ở đây để thể hiện tính năng kế thừa Inheritance thì Java đã sử dụng từ khóa extends - có nghĩa là "mở rộng" tính năng của class ban đầu. Vì vậy nên khi override lại bất kỳ class member nào thì chúng ta cũng chỉ có thể duy trì mức hiển thị đã có, hoặc phải mở rộng hơn (ví dụ private -> protected), chứ chắc chắn là không thể giới hạn nhỏ lại (ví dụ public -> default).

(chưa đăng tải) [Object-Oriented + Java] Bài viết #4 - Abstract Class & Interface

Bình luận

Bài viết tương tự

- vừa được xem lúc

Closure trong Javascript - Phần 2: Định nghĩa và cách dùng

Các bạn có thể đọc qua phần 1 ở đây. Để mọi người không quên, mình xin tóm tắt gọn lại khái niệm lexical environment:.

0 0 66

- vừa được xem lúc

Var vs let vs const? Các cách khai báo biến và hằng trong Javascript

Dạo này mình tập tành học Javascript, thấy có 2 cách khai báo biến khác nhau nên đã tìm tòi sự khác biệt. Nay xin đăng lên đây để mọi người đọc xong hy vọng phân biệt được giữa let và var, và sau đó là khai báo hằng bằng const.

0 0 47

- vừa được xem lúc

VueJS: Tính năng Mixins

Chào mọi người, hôm nay mình sẽ viết về Mixins và 1 số vấn đề trong sử dụng Mixins hay ho mà mình gặp trong dự án thực. Trích dẫn từ trang chủ của VueJS:.

0 0 41

- vừa được xem lúc

Asset Pipeline là cái chi chi?

Asset Pipeline. Asset pipeline là cái chi chi. . Giải thích:.

0 0 72

- vừa được xem lúc

Tạo data table web app lấy dữ liệu từ Google Sheets sử dụng Apps Script

Google Sheets là công cụ tuyệt vời để lưu trữ bảng tính trực tuyến, bạn có thể truy cập bảng tính bất kỳ lúc nào ở bất kỳ đâu và luôn sẵn sàng để chia sẻ với người khác. Bài này gồm 2 phần.

0 0 280

- vừa được xem lúc

Học Deep Learning trên Coursera miễn phí

Bạn muốn bắt đầu với Deep Learning nhưng không biết bắt đầu từ đâu? Bạn muốn có một công việc ở mức fresher về Deep Learning? Bạn muốn khoe bạn bè về kiến thức Deep Learning của mình. Bắt đầu từ đâu.

0 0 50