Daily Archives: 15/08/2017

Java 8 – Package

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.awtjava.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ố staticPI, 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; 
    }
}