Sử dụng nested class và inner class trong Java

Đây là bài 35/62 bài của series môn học Ngôn ngữ lập trình Java

1. Nested class trong Java là gì?

Trong Java, chúng ta có thể định nghĩa một lớp bên trong một lớp khác. Chúng ta gọi lớp nằm bên trong là nested class và lớp bên ngoài là outer class. Ví dụ:

class OuterClass {
    // ...
    class NestedClass {
        // ...
    }
}

Có 2 loại nested class trong Java là:

    • Non-static nested class, còn gọi là inner class
    • Static nested class

2. Non-Static Nested Class (Inner Class)

Một non-static nested class là một lớp nằm bên trong lớp khác. Non-static nested class có thể truy cập vào các thành viên của lớp chứa nó (outer class). Non-static nested class còn được gọi là inner class.

Muốn sử dụng inner class thì phải khởi tạo outer class trước khi khởi tạo inner class.

class AClass {
    int bienA;
    //nested class
    class BClass{
        int bienB;
        void xuatBienB(){
            bienB = 5;
            System.out.println("Gia tri bienB = " + bienB);
        }
    }
    //protected nested class
    protected class CClass{
        int bienC;
        void xuatBienC(){
            bienC = 9;
            System.out.println("Gia tri bienC = " + bienC);
            bienA = 10;
            System.out.println("Gia tri bienA = " + bienA);
        }
    }
}

class Main {
    public static void main(String[] args) {
        AClass ac = new AClass();
        AClass.BClass bc = ac.new BClass();
        AClass.CClass cc = ac.new CClass();
        System.out.println("Lop inner BClass:");
        bc.xuatBienB();
        System.out.println("Lop inner CClass:");
        cc.xuatBienC();
    }
}
Kết quả
Lop inner BClass:
Gia tri bienB = 5
Lop inner CClass:
Gia tri bienC = 9
Gia tri bienA = 10

Trong ví dụ trên, có 2 inner class là BClassCClass ở bên trong outer class là AClass.

Một lớp bình thường chỉ có access modifier là public và mặc định (default). Nhưng một inner class thì như một thành viên của outer class nên có thể khai báo với bất kỳ access modifier nào. Do đó, inner CClass có thể khai báo với access modifierprotected, thậm chí là public, private hay mặc định (default).

Để sử dụng các lớp inner thì phải khởi tạo lớp outer. Trong hàm main(), khởi tạo đối tượng ac của AClass, sử dụng đối tượng này để khởi tạo đối tượng của BClassCClass.

AClass ac = new AClass();
AClass.BClass bc = ac.new BClass();
AClass.CClass cc = ac.new CClass();

Lưu ý: Các lớp inner có thể truy cập các thành viên của outer class. Nhưng các inner class trong cùng một outer class thì không thể truy cập các thành viên của nhau.

Truy cập thành viên của outer class trong inner class

Chúng ta có thể sử dụng từ khóa this để truy cập các thành viên của outer class bên trong inner class.

class Car {
    String carName;
    String carType;
    public Car(String name, String type) {
        this.carName = name;
        this.carType = type;
    }
    private String getCarName() {
        return this.carName;
    }

    //inner class
    class Engine {
        String engineType;
        void setEngine() {
            //truy cập thuộc tính carType của lớp Car
            if(Car.this.carType.equals("4WD")){
                //gọi hàm getCarName() của lớp Car
                if(Car.this.getCarName().equals("Crysler")) {
                    this.engineType = "Smaller";
                } else {
                    this.engineType = "Bigger";
                }
            }else{
                this.engineType = "Bigger";
            }
        }
        String getEngineType(){
            return this.engineType;
        }
    }
}

public class Main {
    public static void main(String[] args) {
        //tạo một đối tượng của outer class Car
        Car car1 = new Car("Mazda", "8WD");
        //tạo môt đối tượng của inner class sử dụng outer class
        Car.Engine engine = car1.new Engine();
        engine.setEngine();
        System.out.println("Engine Type for 8WD= " + engine.getEngineType());
        Car car2 = new Car("Crysler", "4WD");
        Car.Engine c2engine = car2.new Engine();
        c2engine.setEngine();
        System.out.println("Engine Type for 4WD = " + c2engine.getEngineType());
    }
}
Kết quả
Engine Type for 8WD= Bigger
Engine Type for 4WD = Smaller

Các thành viên của outer class được khai báo và private, protected, public hay mặc định (default) đều có thể được truy cập trong inner class. Bởi outer class xem inner class như một thành viên bình thường (thuộc tính, phương thức) của nó.

3. Static Nested Class

Trong Java, chúng ta có thể định nghĩa một static class bên trong một lớp khác với từ khóa static. Được gọi là static nested class. Lưu ý, trong Java, một lớp bình thường không nằm trong lớp khác thì không cho phép khai báo với static.

Không giống inner class, một static nested class không thể được truy cập thông qua một đối tượng của outer class. Mà nó được truy cập thông qua tên của outer class. Ví dụ:

class OuterClass{
    static class StaticNestedClass{
        int bienA = 1;
        int bienB = 5;
        int getSum(){
            return bienA + bienB;
        }
    }
}
public class Main {
    public static void main(String[] args) {
        OuterClass.StaticNestedClass snc = new OuterClass.StaticNestedClass();
        System.out.println("Sum = " + snc.getSum());
    }
}
Kết quả
Sum = 6

Trong ví dụ trên, chúng ta tạo một static nested class StaticNestedClass trong lớp OuterClass. Chúng ta tạo ra một đối tượng của static nested class thông qua tên OuterClass.

OuterClass.StaticNestedClass snc = new OuterClass.StaticNestedClass();

Lưu ý: Các thành viên của outer class không được truy cập trong static nested class. Nếu không sẽ gây ra lỗi.

4. Một số lưu ý khi sử dụng nested class

Trong Java, inner class như một thành viên bình thường của một outer class. Chúng giống như các thuộc tính và phương thức được khai báo bên trong một lớp.

Các inner class có thể được khai báo với bất cứ access modifier nào.

Sử dụng toán tử chấm (.) để lớp outer có thể truy cập đến các lớp inner bên trong nó.

Các lớp inner có thể truy cập các thành viên của lớp outer ngay cả khi chúng được khai báo là private. Nhưng static nested class thì không thể truy cập được các thành viên của lớp outer.

5/5 - (1 bình chọn)
Bài trước và bài sau trong môn học<< Tính đóng gói (encapsulation) trong JavaSử dụng static class và anonymous class trong Java >>
Chia sẻ trên mạng xã hội:

Trả lời

Lưu ý:

1) Vui lòng bình luận bằng tiếng Việt có dấu.

2) Khuyến khích sử dụng tên thật và địa chỉ email chính xác.

3) Mọi bình luận trái quy định sẽ bị xóa bỏ.