Search…

Access Modifiers trong Java

15/12/20204 min read
Các access modifiers trong Java như private, public, protected hỗ trợ tính đóng gói các thuộc tính, phương thức và package.

Giới thiệu

Java là 1 ngôn ngữ lập trình thuần hướng đối tượng, không như ngôn ngữ C++ là các thành phần có thể không nằm ngoài, thành phần bất kỳ trong Java phải nằm trong lớp. So với C++ thì OOP trong Java có 1 số điểm khác biệt.

Bài viết này đề cập tới 4 phạm vi truy xuất tương ứng với 4 access modifiers dành cho thuộc tính và phương thức của lớp: private, default, protected, public.

Access modifiers trong Java

Access modifiers là gì?

Access modifiers là các từ khóa tương ứng với các phạm vi truy xuất vào thuộc tính hoặc phương thức của 1 lớp.

4 Access modifiers trong Java

  • private
  • default
  • protected
  • public

Phạm vi truy xuất do access modifiers quy định được mô tả chi tiết ở bảng dưới đây:

  Trong class Trong package class kế thừa trong package class kế thừa ngoài package
private Được phép Không được phép Không được phép Không được phép
default Được phép Được phép Không được phép Không được phép
protected Được phép Được phép Được phép Không được phép
public Được phép Được phép Được phép Được phép

Các ví dụ về access modifiers

private

private: là phạm vi truy xuất thấp nhất, các thuộc tính, phương thức đánh dấu là private chỉ có thể truy xuất trong lớp đó.

Giả sử có lớp Book có 2 thuộc tính là nameprice.

package com.example.package1;

public class Book {
    private String name;
    private double price;

    public Book() {
    }

    @Override
    public String toString() {
        return "Name: " + name + " - Price: " + price;
    }
}

Và truy cập bên trong lớp cùng package sẽ nhận thông báo lỗi.

package com.example.package1;

public class Program {
    public static void main(String[] args) {
        Book book = new Book();
        book.name = "7 thói quen để thành đạt"; // Lỗi "The field Book.name is not visible"
    }
}

Truy xuất ở lớp kế thừa ngoài package sẽ nhận được lỗi.

package com.example.package2;

import com.example.package1.Book;

public class FoodBook extends Book {
    public void print() {
        System.out.println(this.name); // Lỗi "The field Book.name is not visible"
    }
}

Truy xuất ở lớp không phải lớp kế thừa ngoài package cũng nhận được lỗi tương tự.

package com.example.package2;

import com.example.package1.Book;

public class OutputHelper {
    public static void print(Book book) {
        System.out.println(book.name); // Lỗi "The field Book.name is not visible"
    }
}

default

Mặc định khi khai báo mà không chỉ rõ phạm vi truy xuất thì Java hiểu đó là default (mặc định), access modifier này được truy cập ở trong class, ở các class cùng package và lớp kế thừa cùng package.

Sửa class Book bằng cách xóa các từ khóa private:

package com.example.package1;

public class Book {
    String name;
    double price;

    public Book() {
    }

    @Override
    public String toString() {
        return "Name: " + name + " - Price: " + price;
    }
}

Được phép truy xuất bên trong lớp cùng package.

package com.example.package1;

public class Program {
    public static void main(String[] args) {
        Book book = new Book();
        book.name = "7 thói quen để thành đạt"; // Không lỗi
    }
}

Truy xuất ở lớp kế thừa ngoài package sẽ nhận được lỗi.

Truy xuất ở lớp kế thừa ngoài package xảy ra lỗi.

Truy xuất ở lớp không phải lớp kế thừa ngoài package.

protected

protected có phạm vi truy xuất rộng hơn default là có thể truy xuất ở class kế thưa cho dù class đó nằm ngoài hay trong package và không được truy xuất ở các lớp không phải là lớp con ở ngoài package.

Sửa đổi các phạm vi truy xuất của các thuộc tính trong class Book thành protected.

package com.example.package1;

public class Book {
    protected String name;
    protected double price;

    public Book() {
    }

    @Override
    public String toString() {
        return "Name: " + name + " - Price: " + price;
    }
}

Và được phép truy cập bên trong lớp cùng package.

package com.example.package1;

public class Program {
    public static void main(String[] args) {
        Book book = new Book();
        book.name = "7 thói quen để thành đạt"; // Không lỗi
    }
}

Cho phép truy xuất ở lớp kế thừa ngoài package.

package com.example.package2;

import com.example.package1.Book;

public class FoodBook extends Book {
    public void print() {
        System.out.println(this.name); // Không lỗi
    }
}

Không cho phép truy cập các lớp không phải lớp con ngoài package.

package com.example.package2;

import com.example.package1.Book;

public class OutputHelper {
    public static void print(Book book) {
        System.out.println(book.name); // Lỗi "The field Book.name is not visible"
    }
}

public

public là phạm vi truy xuất rộng nhất, ở bất kỳ tầm vực nào cũng có thể truy xuất được.

Sửa đổi các trường của class Book thành public.

package com.example.package1;

public class Book {
    public String name;
    public double price;

    public Book() {
    }

    @Override
    public String toString() {
        return "Name: " + name + " - Price: " + price;
    }
}

Được phép truy xuất ở lớp trong cùng package

Được phép truy xuất ở lớp kế thừa ngoài package.

Được phép truy xuất ở lớp không phải là lớp kế thừa ngoài package.

Kết luận

Theo nguyên tắc thiết kế hướng đối tượng thì các thuộc tính của class nên để là private và truy cập thông qua các phương thức getter/setter. Nếu để chúng public sẽ phá vỡ nguyên tắc đóng gói của hướng đối tượng.

IO Stream

IO Stream Co., Ltd

30 Trinh Dinh Thao, Hoa Thanh ward, Tan Phu district, Ho Chi Minh city, Vietnam
+84 28 22 00 11 12
developer@iostream.co

383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2024