Việc sử dụng các công cụ sửa đổi truy cập thành viên ít hạn chế hơn so với công cụ sửa đổi truy cập lớp là gì?


9

Giả sử tôi có một lớp với một số thành viên và các thành viên có công cụ sửa đổi truy cập ít hạn chế hơn so với chính lớp đó.

Một ví dụ cụ thể có thể là:

package apples;

class A { // package private
    public int foo() { // public (=> less restrictive than *package private*)
        return 42;
    }
}

Theo hiểu biết của tôi, một công cụ sửa đổi truy cập lớp hạn chế hơn công cụ sửa đổi truy cập thành viên , sẽ ghi đè lên công cụ sửa đổi truy cập thành viên ít hạn chế hơn . Vì vậy, một sửa đổi truy cập thành viên ít hạn chế hơn sẽ không có hiệu lực nào cả.

  • Tôi hiểu có đúng không?
    • Nếu không, hậu quả là gì?
  • Điều gì có thể là lý do hợp lệ để có sửa đổi truy cập thành viên ít hạn chế hơn?
  • Cuối cùng, những gì là thực hành tốt nhất để làm theo?

Tôi cũng đã thực hiện một số thử nghiệm vì tôi nghĩ rằng nó có thể có hậu quả khi tôi bắt đầu chuyển các tham chiếu hàm xung quanh, tuy nhiên ngay cả khi đó công cụ sửa đổi truy cập dường như không quan trọng.

Tình huống mà tôi xây dựng như sau:

  • apples.Bcung cấp một phương thức công khai bla()trả về một tham chiếu đến apples.A.foo.
  • Sau đó pizzas.Cgọi apples.B.blađể có được một tài liệu tham khảo A.foovà gọi nó.
  • Vì vậy, A.foo()không thể nhìn thấy trực tiếp C, nhưng chỉ có thể truy cập gián tiếp thông quaB.bla()

Tôi đã thử nghiệm nó và nó không tạo ra sự khác biệt cho dù tôi có sửa đổi truy cập của foo() gói riêng tư hay không.

package apples;

import java.util.function.IntSupplier;

public class B {
    public IntSupplier getReferenceToAFoo() {
        A aInstance = new A();
        return aInstance::foo;
    }
}
package pizzas;

import apples.B;

import java.util.function.IntSupplier;

public class C {
    private int callAFooIndirectly() {
        B bInstance = new B();
        IntSupplier intsupplier = bInstance.getReferenceToAFoo();
        return intsupplier.getAsInt();
    }

    public static void main(String[] args) {
        C cInstance = new C();

        int i = cInstance.callAFooIndirectly();
        System.out.println(i);
        assert 42 == i;
    }
}

2
Lý do phổ biến nhất cho đến nay đối với loại thiết kế này là cung cấp việc triển khai các phương thức API công khai (chẳng hạn như các phương thức từ giao diện hoặc các lớp trừu tượng mở rộng) bằng cách sử dụng các lớp không công khai. JDK chính nó là trang bị đầy đủ với các lớp học như vậy (ví dụ: java.util.Collections.SingletonSet<E>privatetrong java.util.Collections).
ernest_k

Câu trả lời:


8

Tôi hiểu có đúng không?

Đúng.

Điều gì có thể là lý do hợp lệ để có sửa đổi truy cập thành viên ít hạn chế hơn?

Hai lý do:

  • Đôi khi, bạn đang thực hiện một giao diện; phương pháp giao diện phảipublic
  • Nó làm cho nó dễ dàng hơn để thay đổi truy cập tổng thể của lớp của bạn. Chẳng hạn, nếu bạn đánh dấu tất cả các phương thức mà bạn muốn công khai public, ngay cả trong một lớp riêng tư, thì sau đó tất cả những gì bạn phải làm để làm cho lớp công khai được thêm publicvào khai báo lớp.

Cuối cùng, những gì là thực hành tốt nhất để làm theo?

Đó là vấn đề quan điểm, vì vậy không phù hợp với câu hỏi hoặc câu trả lời Stack Overflow. Làm những gì có vẻ hợp lý với bạn và / hoặc nhóm của bạn và / hoặc làm những gì hướng dẫn về phong cách của đội bạn bảo bạn làm.

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.