Truy cập các đối tượng lồng nhau javascript

Ngôn ngữ lập trình Java cho phép bạn định nghĩa một lớp trong một lớp khác. Một lớp như vậy được gọi là một lớp lồng nhau và được minh họa ở đây

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


Thuật ngữ. Các lớp lồng nhau được chia thành hai loại. không tĩnh và tĩnh. Các lớp lồng nhau không tĩnh được gọi là các lớp bên trong. Các lớp lồng nhau được khai báo
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
4 được gọi là các lớp lồng nhau tĩnh

class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}

Một lớp lồng nhau là một thành viên của lớp kèm theo của nó. Các lớp lồng nhau không tĩnh (các lớp bên trong) có quyền truy cập vào các thành viên khác của lớp kèm theo, ngay cả khi chúng được khai báo là riêng tư. Các lớp lồng nhau tĩnh không có quyền truy cập vào các thành viên khác của lớp kèm theo. Là một thành viên của

class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
5, một lớp lồng nhau có thể được khai báo
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
6,
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
7,
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
8 hoặc gói private. (Nhớ lại rằng các lớp bên ngoài chỉ có thể được khai báo
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
7 hoặc gói private. )

Tại sao nên sử dụng các lớp lồng nhau?

Lý do thuyết phục để sử dụng các lớp lồng nhau bao gồm những điều sau đây

  • Đó là một cách nhóm hợp lý các lớp chỉ được sử dụng ở một nơi. Nếu một lớp chỉ hữu ích cho một lớp khác, thì việc nhúng nó vào lớp đó và giữ cả hai lại với nhau là điều hợp lý. Việc lồng các "lớp trợ giúp" như vậy làm cho gói của chúng được sắp xếp hợp lý hơn

  • Nó làm tăng khả năng đóng gói. Xem xét hai lớp cấp cao nhất, A và B, trong đó B cần truy cập vào các thành viên của A mà nếu không sẽ được khai báo

    class OuterClass {
        ...
        class InnerClass {
            ...
        }
        static class StaticNestedClass {
            ...
        }
    }
    
    6. Bằng cách ẩn lớp B trong lớp A, các thành viên của A có thể được khai báo là riêng tư và B có thể truy cập chúng. Ngoài ra, bản thân B có thể bị ẩn khỏi thế giới bên ngoài

  • Nó có thể dẫn đến mã dễ đọc và dễ bảo trì hơn. Việc lồng các lớp nhỏ trong các lớp cấp cao nhất sẽ đặt mã gần hơn với nơi nó được sử dụng

lớp học bên trong

Như với các phương thức và biến thể hiện, một lớp bên trong được liên kết với một thể hiện của lớp kèm theo của nó và có quyền truy cập trực tiếp vào các phương thức và trường của đối tượng đó. Ngoài ra, vì một lớp bên trong được liên kết với một thể hiện, nên nó không thể tự định nghĩa bất kỳ thành viên tĩnh nào

Các đối tượng là thể hiện của lớp trong tồn tại trong thể hiện của lớp ngoài. Hãy xem xét các lớp sau

class OuterClass {
    ...
    class InnerClass {
        ...
    }
}

Một phiên bản của

class OuterClass {
    ...
    class InnerClass {
        ...
    }
}
1 chỉ có thể tồn tại trong một phiên bản của
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
5 và có quyền truy cập trực tiếp vào các phương thức và trường của phiên bản kèm theo của nó

Để khởi tạo một lớp bên trong, trước tiên bạn phải khởi tạo lớp bên ngoài. Sau đó, tạo đối tượng bên trong đối tượng bên ngoài bằng cú pháp này

class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
2

Có hai loại lớp bên trong đặc biệt. lớp cục bộ và lớp ẩn danh

Các lớp lồng nhau tĩnh

Như với các phương thức và biến của lớp, một lớp lồng tĩnh được liên kết với lớp bên ngoài của nó. Và giống như các phương thức của lớp tĩnh, một lớp lồng tĩnh không thể tham chiếu trực tiếp đến các biến thể hiện hoặc các phương thức được định nghĩa trong lớp kèm theo của nó. nó chỉ có thể sử dụng chúng thông qua một tham chiếu đối tượng. Ví dụ về Inner Class và Nested Static Class chứng minh điều này


Ghi chú. Một lớp lồng tĩnh tương tác với các thành viên thể hiện của lớp bên ngoài của nó (và các lớp khác) giống như bất kỳ lớp cấp cao nhất nào khác. Trên thực tế, một lớp lồng tĩnh về mặt hành vi là một lớp cấp cao nhất đã được lồng trong một lớp cấp cao nhất khác để thuận tiện cho việc đóng gói. Ví dụ về Inner Class và Nested Static Class cũng chứng minh điều này

Bạn khởi tạo một lớp lồng tĩnh giống như một lớp cấp cao nhất

class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
3

Ví dụ sau,

class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
5, cùng với
class OuterClass {
    ...
    class InnerClass {
        ...
    }
}
4, chứng minh các thành viên lớp nào của
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
5, lớp bên trong (
class OuterClass {
    ...
    class InnerClass {
        ...
    }
}
1), lớp tĩnh lồng nhau (
class OuterClass {
    ...
    class InnerClass {
        ...
    }
}
7) và lớp cấp cao nhất (
class OuterClass {
    ...
    class InnerClass {
        ...
    }
}
4) có thể truy cập

lớp ngoài. java

class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
0

TopLevelLớp. java

class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
1

Ví dụ này in đầu ra sau

class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
2

Lưu ý rằng một lớp lồng tĩnh tương tác với các thành viên thể hiện của lớp bên ngoài giống như bất kỳ lớp cấp cao nhất nào khác. Lớp lồng tĩnh

class OuterClass {
    ...
    class InnerClass {
        ...
    }
}
7 không thể truy cập trực tiếp vào
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
20 vì nó là một biến thể hiện của lớp kèm theo,
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
5. Trình biên dịch Java tạo ra lỗi tại câu lệnh được đánh dấu

class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
6

Để khắc phục lỗi này, hãy truy cập

class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
20 thông qua tham chiếu đối tượng

class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
8

Tương tự, lớp cấp cao nhất

class OuterClass {
    ...
    class InnerClass {
        ...
    }
}
4 cũng không thể truy cập trực tiếp vào
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
20

Nếu một khai báo của một kiểu (chẳng hạn như một biến thành viên hoặc một tên tham số) trong một phạm vi cụ thể (chẳng hạn như một lớp bên trong hoặc một định nghĩa phương thức) có cùng tên với một khai báo khác trong phạm vi kèm theo, thì khai báo đó sẽ che dấu khai báo đó . Bạn không thể tham chiếu đến một khai báo ẩn chỉ bằng tên của nó. Ví dụ sau đây,

class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
25, chứng minh điều này

class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
0

Sau đây là đầu ra của ví dụ này

class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
1

Ví dụ này định nghĩa ba biến có tên là

class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
26. biến thành viên của lớp
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
25, biến thành viên của lớp bên trong
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
28 và tham số trong phương thức
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
29. Biến
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
26 được định nghĩa là một tham số của phương thức
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
29 che khuất biến của lớp bên trong
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
28. Do đó, khi bạn sử dụng biến
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
26 trong phương thức
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
29, nó đề cập đến tham số phương thức. Để tham chiếu đến biến thành viên của lớp bên trong
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
28, hãy sử dụng từ khóa
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
36 để biểu thị phạm vi kèm theo

class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
2

Tham khảo các biến thành viên bao quanh phạm vi lớn hơn theo tên lớp mà chúng thuộc về. Ví dụ, câu lệnh sau truy cập biến thành viên của lớp

class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
25 từ phương thức
class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
29

class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
3

Tuần tự hóa các lớp bên trong, bao gồm các lớp cục bộ và ẩn danh, không được khuyến khích. Khi trình biên dịch Java biên dịch các cấu trúc nhất định, chẳng hạn như các lớp bên trong, nó sẽ tạo ra các cấu trúc tổng hợp; . Cấu trúc tổng hợp cho phép trình biên dịch Java triển khai các tính năng ngôn ngữ Java mới mà không cần thay đổi JVM. Tuy nhiên, các cấu trúc tổng hợp có thể khác nhau giữa các triển khai trình biên dịch Java khác nhau, điều đó có nghĩa là các tệp

class OuterClass {
    ...
    class InnerClass {
        ...
    }
    static class StaticNestedClass {
        ...
    }
}
39 cũng có thể khác nhau giữa các triển khai khác nhau. Do đó, bạn có thể gặp sự cố tương thích nếu bạn tuần tự hóa một lớp bên trong và sau đó giải tuần tự hóa nó bằng một triển khai JRE khác. Xem phần Tham số ẩn và tổng hợp trong phần Lấy tên của tham số phương thức để biết thêm thông tin về các cấu trúc tổng hợp được tạo khi một lớp bên trong được biên dịch