Gói (Package) là một tính năng hỗ trợ coder tìm kiểu dữ liệu nhanh chóng, tránh trùng lắp tên, tiện dụng trong truy vấn.
Một gói (package) là một nhóm các kiểu dữ liệu có liên quan tới nhau hỗ trợ truy cập và quản lý các kiểu dữ liệu đó, kiểu dữ liệu ở đây có thể là lớp, interface, enum, annotation, tuy nhiên trong bài này chúng ta sẽ chủ yếu làm việc với lớp.
Tất cả các lớp có sẵn trong Java đều được nhóm vào một gói nào đó, chẳng hạn như các lớp cơ bản thì được nhóm vào trong gói java.lang
, các lớp hỗ trợ đọc/ghi dữ liệu thì nằm trong gói java.io
, chúng ta cũng có thể tự định nghĩa gói riêng và nhóm các lớp của chúng ta lại vào gói này.
Tạo một gói
Để tạo một gói thì chúng ta ghi từ khóa package
theo sau là tên gói do chúng ta tự nghĩ vào đầu mỗi file .java
có chứa code định nghĩa kiểu (như lớp, interface, annotation…). Lưu ý là câu lệnh package này phải được ghi đầu tiên trong mỗi file code Java, và trong mỗi file chỉ được phép có duy nhất một dòng này thôi.
Thông thường thì chúng ta sẽ định nghĩa mỗi kiểu dữ liệu mới trong mỗi file riêng biệt, chẳng hạn như lớp public class Blog
thì trong file Blog.java
, lớp public class PhoCodeBlog
trong file PhoCodeBlog.java
…v.v Và trong mỗi file này chúng ta chèn thêm câu lệnh package (chẳng hạn package blog;
) vào đầu mỗi file để quy định package cho chúng.
package blog; public class Blog { // ... }
package blog; public class PhoCodeBlog { // ... }
Nếu chúng ta không ghi dòng lệnh package
nào thì các kiểu mà chúng ta định nghĩa ra sẽ không có package.
Quy tắc đặt tên
Tên package được viết thường toàn bộ các chữ cái để tránh nhầm lẫn với tên lớp hoặc interface.
Thông thường thì các package được viết bởi các công ty sẽ có tên bắt đầu bằng tên miền do công ty đó mua. Chẳng hạn như công ty FPT viết package sẽ có tên dạng như com.fpt.mypackage
.
Các package có sẵn trong Java có tên bắt đầu bằng java.
hoặc javax.
Truy xuất các phần tử trong package
Các kiểu dữ liệu được định nghĩa bên trong một package được gọi là các phần tử của package. Chúng ta có thể truy xuất phần tử của một package bằng một trong các cách sau:
- Viết đầy đủ tên của lớp và package
- Import tên phần tử của package
- Import tất cả các phần tử của package
Nếu bạn đã từng làm việc với C++ hay C# thì có thể hiểu import
giống như include
hoặc using
vậy
Viết đầy đủ tên lớp và package
Chúng ta sử dụng cách viết này bằng cách viết tên đầy đủ của gói và tên của kiểu dữ liệu, ngăn cách nhau bởi dấu chấm. Ví dụ:
blog.PhoCodeBlog;
Tuy nhiên nếu gói mà chúng ta định sử dụng đã được import trước rồi (tìm hiểu thêm ở dưới) thì chúng ta không cần phải ghi tên gói ra nữa mà chỉ cần ghi tên kiểu dữ liệu là được.
Để tạo một đối tượng lớp PhoCodeBlog
thì chúng ta cũng phải ghi đầy đủ tên gói và tên lớp ra:
blog.PhoCodeBlog blog = new blog.PhoCodeBlog();
Thông thường chúng ta sử dụng cách ghi đầy đủ này nếu như kiểu dữ liệu đó ít được dùng. Còn nếu đây là lớp thường dùng thì chúng ta nên sử dụng cách import package.
Import phần tử của package
Chúng ta import một kiểu dữ liệu (hay một phần tử) trong một package bằng cách ghi từ khóa import
vào đầu file, theo sau là tên đầy đủ của package và lớp, ngăn cách nhau bởi dấu chấm. Ví dụ:
import blog.PhoCodeBlog;
Các dòng import
luôn luôn đứng đầu file nhưng phải đứng sau dòng khai báo package
.
Sau khi đã import thì chúng ta có thể tạo đối tượng lớp bình thường mà không cần ghi tên package:
PhoCodeBlog blog = new PhoCodeBlog();
Cách import
trực tiếp như thế này thường được dùng khi kiểu dữ liệu được gọi đi gọi lại nhiều lần. Nếu một package có nhiều kiểu dữ liệu và chúng ta cũng thường xuyên sử dụng các kiểu dữ liệu đó thì chúng ta nên sử dụng cách import toàn bộ phần tử của package.
Import tất cả các phần tử của package
Để import toàn bộ phần tử trong một package thì chúng ta ghi dấu ngôi sao (*
) theo sau tên package thay vì ghi rõ tên các phần tử. Ví dụ:
import blog.*;
Và chúng ta vẫn có thể sử dụng các phần tử của package một cách bình thường.
PhoCodeBlog blog = new PhoCodeBlog();
Package không có tính thừa kế hay gộp nhóm
Package không có tính thừa kế hay gộp nhóm như class. Ví dụ trong Java có package java.awt
, một package khác có tên là java.awt.color
, và java.awt.font
, java.awt.xxx
… thì đây là các package riêng biệt, tức là java.awt.color
không liên quan gì tới java.awt
cả, mà đây thực ra chỉ là quy tắc đặt tên package trong Java cho dễ quản lý. Khi chúng ta ghi import java.awt.*
thì dòng này chỉ đọc các phần tử có trong package java.awt
chứ không liên quan gì tới các package có trong java.awt.color
hay java.awt.font
…v.v
Để sử dụng tất cả các phần tử của cả 2 package java.awt
và java.awt.color
thì chúng ta phải import cả 2 package:
import java.awt.*; import java.awt.color.*;
Package có các phần tử trùng tên
Nếu có 2 package khác nhau có các phần tử trùng tên, và cả 2 đều được import thì khi sử dụng, chúng ta phải chỉ rõ tên package của phần tử mà chúng ta định sử dụng. Chẳng hạn như chúng ta định nghĩa một lớp có tên Integer
trong package blog
, thì lớp này trùng với lớp Integer
trong package java.lang
và do đó khi sử dụng chúng ta phải ghi rõ tên package của lớp mà chúng ta muốn sử dụng.
import blog.Integer; import java.lang.Integer; Integer a = new Integer(); // lỗi java.lang.Integer b = new java.lang.Integer(); // đúng blog.Integer c = new blog.Integer(); // đúng
Static Import
Trong Java có câu lệnh static import
dùng để import các thành phần static
của các lớp có trong các package, thường thì chúng ta sẽ import những phần tử hay được dùng nhiều nhất.
Chẳng hạn như lớp Math
trong package java.lang
có hằng số static
là PI
, khi dùng thì chúng ta sẽ gọi tên lớp và tên hằng số một cách rõ ràng là java.lang.Math.PI
:
public class Circle { // Hình tròn private double r; public static double area() // Tính diện tích { return java.lang.Math.PI * this.r * this.r; } }
Chúng ta có thể import
lớp Math
bằng cách ghi câu lệnh import java.lang.Math;
sau đó mỗi lần dùng PI
thì ghi Math.PI
. Hoặc nếu muốn gọn hơn thì chúng ta có thể import
luôn hằng số PI
như sau:
import static java.lang.Math.PI;
Hoặc dùng cách import toàn bộ phần tử:
import static java.lang.Math.*;
Bằng cách đó chúng ta có thể ghi PI
đứng một mình là được:
import static java.lang.Math.PI; public class Circle { // Hình tròn private double r; public static double area() // Tính diện tích { return PI * this.r * this.r; } }