Tại sao không có công cụ sửa đổi truy cập 'chỉ phân lớp' trong Java?


16

Trong Java, có bốn công cụ sửa đổi truy cập có sẵn cho các phương thức:

public - bất kỳ lớp nào cũng có thể sử dụng phương pháp này.

protected - các lớp trong cùng một gói và các lớp con trong bất kỳ gói nào có thể sử dụng phương thức này.

private - chỉ có lớp này có thể sử dụng phương pháp này.

no modifier ("gói riêng") - chỉ các lớp trong cùng một gói có thể sử dụng phương thức này.

Điều thường xảy ra là tôi muốn có các phương thức hữu ích trong một siêu lớp, mà tất cả các lớp con có thể sử dụng. Nhưng nó sẽ không có ý nghĩa đối với các lớp khác để truy cập phương thức này và theo một nghĩa nào đó, nó sẽ phá vỡ sự đóng gói.

Vì vậy, tôi phải khai báo các phương thức hữu ích này trong lớp cha publichoặc protected, chúng hiển thị chúng cho tất cả các lớp khác ít nhất là trong gói. Mặc dù chúng chỉ được sử dụng bởi các lớp con.

Có một lý do tại sao không có một công cụ subclasses-onlysửa đổi truy cập trong Java? Nó có vẻ rất kỳ lạ với tôi. Tui bỏ lỡ điều gì vậy?

Ngoài ra, một công cụ subclasses-onlysửa đổi truy cập cũng sẽ hữu ích khi bạn muốn chỉ hiển thị các biến cho các lớp con. Mà với tôi xảy ra rất nhiều.

Câu trả lời:


10

Bởi vì bạn có thể mô phỏng công cụ sửa đổi chỉ các lớp con bằng cách sử dụng công cụ sửa đổi được bảo vệ và thực thi rằng chỉ có lớp cha và các lớp con của nó nằm trong cùng một gói.

Đó thực sự là một thực tiễn tốt, bởi vì các gói không chỉ giúp tổ chức các dự án lớn về sự gắn kết, mà chúng còn cho thấy rằng các lớp trong cùng một gói có thể có một số mức độ khớp nối.


15
"Và thực thi rằng chỉ có lớp cha và các lớp con của nó nằm trong cùng một gói" - Bây giờ, làm thế nào để làm điều đó?!
JimmyB

1
Và sau đó bạn không thể sử dụng công cụ sửa đổi truy cập chỉ gói. Và bạn cần một số lượng ngớ ngẩn của các gói. Đây không phải là một giải pháp thực tế.
user253751

13

Java ban đầu có một sửa đổi như vậy. Nó đã được viết private protectednhưng bị xóa trong Java 1.0.

Tôi cho rằng đó là một lời kêu gọi phán xét rằng sự phức tạp thêm không đáng giá.

Mỗi tính năng ngôn ngữ đều có một chi phí: trong việc dạy nó cho các lập trình viên mới; trong tài liệu; trong việc thực hiện nó trong trình biên dịch, JVM và các công cụ dev; trong lý luận về tính đúng đắn của chương trình; trong việc kìm hãm sự phát triển ngôn ngữ trong tương lai; và hơn thế nữa. Các tính năng ngôn ngữ tương tác với nhau, có khả năng tương tác N 2 .

Bao nhiêu phần trăm lập trình viên Java đã đọc qua thông số kỹ thuật Java và thông số VM? Tôi cá rằng đó là một tỷ lệ nhỏ, lập luận cho một ngôn ngữ thậm chí đơn giản hơn vì mục đích dễ hiểu và các sản phẩm kỹ thuật mà chúng ta có thể phụ thuộc vào

Lợi ích của private protectedtính năng là nhỏ vì gói là đơn vị chính của mô đun.


1
vậy có phiên bản Java nào trước 1.0 không?
Mark Yisri

1
@MarkYisri Java đã có các bản phát hành alpha và beta công khai vào năm 1995 và một đoạn mã hợp lý đã được viết để chống lại chúng.
David Moles

4

Kiểm soát Acess có thể được coi là kết quả của sự bao trùm với một nhà phát triển tưởng tượng đang làm việc với lớp của bạn về các phương thức và phương pháp của lớp ...

BẠN: Giả sử bạn muốn làm x, bạn gọi phương thức doX .. DEV: Nói cho tôi biết thêm .. các đối số là gì?

Đây là công khai ...

BẠN: Bên trong doX tôi gọi ... DEV: Whoa, quá nhiều thông tin, tôi không quan tâm đến điều đó. Tôi chỉ muốn biết làm thế nào để sử dụng nó. Nói cho tôi một cái gì đó khác.

Đây là riêng tư ...

BẠN: Khi phân lớp, tôi có doX và doY gọi doIt mà .. DEV: Vâng, tôi sẽ phân lớp, nói cho tôi biết thêm ...

Điều này được bảo vệ ...

BẠN: Tôi sẽ đi nghỉ trong một giờ, tôi sẽ đi trong 6 tháng tới. Ông chủ nói con chó con này là của bạn! Tạm biệt. DEV: Đợi chưa đi, nói cho tôi biết tất cả ...

Đây là gói.

BẠN: Phương thức doItWhen chỉ được gọi bởi lớp này và nó đã không thay đổi trong mười năm. Nó ... DEV: Whoa, chúng tôi xuống còn 50 phút. Tài sản tiếp theo, và nói chuyện nhanh hơn.

Điều này được bảo vệ riêng tư ...


3

Điều này đã tồn tại. Nó được bảo vệ.

Bạn có quyền kiểm soát những gì các lớp tồn tại trong gói. Nếu không có lớp nào khác trong gói và một biến hoặc phương thức đã cho được bảo vệ, thì đó là 'chỉ các lớp con'.

Điều đó nói rằng, một lần nữa, bạn có quyền kiểm soát những lớp tồn tại trong gói. Bạn có thể chọn không sử dụng các phương thức hoặc biến được bảo vệ.


3
Ngoài các gói hệ thống dành riêng nhất định, tôi không thể thêm một lớp vào bất kỳ gói nào, thậm chí một trong các gói mà bạn không có ý định cho tôi thêm các lớp vào?
David Moles

@David IIRC có, nhưng nó sẽ không cho phép bạn truy cập các trường gói từ một JAR khác vì vậy ngay cả khi bạn đặt nó trong cùng một gói, nếu trong JAR khác, bạn không thể truy cập nó. Tuy nhiên, nếu bạn đang đề cập đến trong cùng một JAR, thì có, bạn có thể truy cập nó, nhưng nếu bạn có thể sửa đổi JAR trong câu hỏi, bạn có thể dễ dàng thay đổi công cụ sửa đổi truy cập.
Pokechu22

1
@ Pokechu22 Tôi nghĩ bạn phải xác nhận niêm phong JAR để có được sự bảo vệ đó, nhưng điểm tốt.
David Moles
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.