Tại sao có phương pháp tĩnh riêng?


68

Tôi chỉ muốn làm sáng tỏ một câu hỏi tôi có. Điểm có một phương thức tĩnh riêng so với phương thức bình thường có khả năng hiển thị riêng là gì?

Tôi có thể nghĩ rằng một lợi thế của việc có một phương thức tĩnh là nó có thể được gọi mà không cần một thể hiện của một lớp, nhưng vì riêng tư của nó thậm chí còn có một điểm để nó là tĩnh?

Lý do duy nhất tôi có thể nghĩ đến là nó giúp khái niệm hiểu phương thức ở cấp độ lớp đối lập với cấp đối tượng.


32
Vâng, có một lý do. Các phương thức tĩnh công khai / mặc định của bạn vẫn có thể gọi các thống kê riêng của bạn. Liệu các phương thức tĩnh có nên được sử dụng hay không và khi thích hợp sử dụng các phương thức riêng tư dưới bất kỳ hình thức nào, là những câu hỏi riêng biệt, vì vậy hãy cẩn thận không trộn lẫn chúng với câu hỏi này.

2
Ví dụ nhanh - phương thức nhà máy được sử dụng bởi một lớp bên trong ngăn chặn sự gọi của các lớp khác (bạn phải thực hiện phương thức nhà máy để lấy một thể hiện của lớp).

2
@MattFenwick: bạn nên đăng bài này như một câu trả lời.
Doc Brown

9
Bằng cách làm cho một phương thức tĩnh, bạn cũng nói rằng nó không đọc hoặc ghi vào các biến thể hiện. Một phương thức không tương tác với các biến thể hiện thường dễ dàng di chuyển và tái cấu trúc đến các nơi khác.
Mark Rogers

1
Đừng quên rằng bất kể phương thức tĩnh là riêng tư, nội bộ hay công khai, nó vẫn không an toàn cho luồng mà không cần nỗ lực đồng bộ hóa mã cụ thể từ phía bạn.
Craig

Câu trả lời:


70

Các đặc tính của tĩnh là độc lập với tầm nhìn.

Những lý do mà bạn sẽ muốn có một phương thức tĩnh (một số mã không phụ thuộc vào các thành viên không tĩnh) vẫn sẽ hữu ích. Nhưng có lẽ bạn không muốn bất cứ ai / bất cứ điều gì khác sử dụng nó, chỉ là lớp học của bạn.


3
Tôi nghĩ rằng bạn đang đi đúng hướng, nhưng tôi cũng nghĩ rằng bạn đang thiếu một điểm quan trọng. Hầu hết các phương thức tĩnh không có tác dụng phụ (chúng là các chức năng hiệu quả, không phải phương thức) - đó là lý do tại sao chúng được tạo tĩnh ngay từ đầu. Lập luận chống lại họ là riêng tư là "Nếu họ không có tác dụng phụ, tại sao không công khai chúng để thúc đẩy tái sử dụng mã". Đó là điểm mấu chốt: khi chúng tôi đặt nó ở chế độ riêng tư, thường là vì chúng tôi muốn bạn sử dụng lại toàn bộ lớp sử dụng phương thức riêng đó, không chỉ phương thức đó.
corsiKa

Tôi phải nói rằng tôi chưa bao giờ làm điều đó hoặc thấy hành vi đó. Một vài lần tôi đã thực hiện nó là cho các phương thức của trình trợ giúp cho các lớp tĩnh công khai.
Miyamoto Akira

1
@corsiKa: Tác dụng phụ không phải là vấn đề. Làm cho một thành viên tĩnh của một lớp không riêng tư hứa hẹn một cách hiệu quả rằng mọi phiên bản tương lai của một lớp sẽ bao gồm cùng một phương thức cùng tên thực hiện cùng một điều. Nếu nhu cầu thay đổi và một phiên bản tương lai của lớp có thể không cần một phương thức hoạt động chính xác như phương thức hiện tại, một phương thức riêng tư có thể được thay thế một cách an toàn bằng một phương pháp đáp ứng tốt hơn các nhu cầu mới của lớp. Như một ví dụ đơn giản, giả sử một lớp học cần có một phương pháp mà phải mất một chuỗi và thực hiện thay thế như <để &lt;, vv Khi nó được viết ...
supercat

1
... các dây mà nó được truyền được biết là không có bất kỳ ampersands, và nó như vậy không chuyển đổi &để &amp;[được tôi viết code, tôi muốn chuyển đổi &để &amp;ngay cả khi tôi không mong đợi nó là cần thiết, nhưng giả sử nó không] Nó sau này nó trở nên cần thiết để xử lý ampersands, nhưng phương pháp này là công khai, thay đổi nó để mở rộng &để &amp;có thể phá vỡ mã bên ngoài mà thực hiện riêng của mình &-to- &amp;thay. Tuy nhiên, nếu phương thức này là riêng tư, nó có thể được sửa để xử lý &mà không gây ra sự cố cho bất kỳ mã bên ngoài nào.
supercat

Đó là một vấn đề thú vị để nói rằng ít nhất, nhưng tôi không thấy cách nó tĩnh khiến nó trở thành vấn đề hơn là không tĩnh, đó là chìa khóa cho vấn đề này. Nếu chúng tôi tuân theo logic của bạn, mọi thứ ở mọi nơi sẽ thực hiện lại mọi thứ vì "omg, nếu có lỗi hoặc yêu cầu thay đổi một ngày nào đó thì sao?"
corsiKa

26

Một lý do khá phổ biến (trong Java) sẽ là để khởi tạo các biến trường bất biến trong một hàm tạo bằng cách sử dụng một private staticphương thức đơn giản để giảm sự lộn xộn của hàm tạo.

  • Đó là private: các lớp bên ngoài không nên nhìn thấy nó.
  • Đó là static: nó có thể thực hiện một số hoạt động, độc lập 1 về trạng thái của lớp máy chủ.

Một ví dụ có phần khó hiểu sau ...

ví dụ:

public class MyClass{
    private final String concatenated;

    public MyClass(String a, String b){
        concatenated = concat(a,b);
    }

    public String getConcatenated(){
       return concatenated;
    }

    /**
    *  Concatenates two Strings as `s1---s2`
    **/
    private static final String concat(String s1, String s2){
        return String.format("%s---%s", s1, s2);
    }
}

1 Giả sử nó không có tương tác với các staticbiến khác .


15
Điều này thậm chí còn có giá trị hơn khi bạn cần chuyển các đối số dẫn xuất (được tính toán) cho hàm tạo của lớp cha. Cuộc super(...)gọi phải là dòng đầu tiên của hàm tạo của lớp bạn, vì vậy bạn không thể khai báo các biến cục bộ để giúp bạn tìm ra những gì cần chuyển đến siêu cuộc gọi. Tuy nhiên, bạn có thể gọi các phương thức tĩnh (riêng tư), sử dụng càng nhiều dòng càng cần thiết để tìm ra giá trị để truyền cho siêu cấu trúc.
Andrzej Doyle

lưu ý rằng có khả năng khối khởi tạo tĩnh
Franz Ebner

13

Một trường hợp sử dụng phổ biến cho một private staticphương thức là một phương thức tiện ích

  1. chỉ được sử dụng bởi một lớp
  2. độc lập với trạng thái bên trong của lớp đó

12

Bạn thấy rằng bạn có một vài dòng mã được lặp lại trong rất nhiều phương thức của bạn, vì vậy bạn quyết định trích xuất chúng thành một phương thức duy nhất, vì mã trùng lặp là không tốt.

Bạn đặt phương thức này ở chế độ riêng tư vì nó không được thiết kế để sử dụng rộng rãi và bạn không muốn mã không liên quan gọi nó. (Tranh luận về điểm này trong phần bình luận.)

Vì phương thức này không truy cập vào bất kỳ trường đối tượng nào, nên nó có thể được tạo tĩnh, bằng cách làm cho nó tĩnh, bạn sẽ dễ hiểu hơn và thậm chí có thể nhanh hơn một chút.

Sau đó .... (Có thể bây giờ, có thể sau này, có thể không bao giờ)

Một khi phương thức đã được thực hiện tĩnh, rõ ràng là nó có thể được chuyển ra khỏi lớp, nói với một lớp thống nhất.

Nó cũng dễ dàng chuyển đổi nó thành một phương thức thể hiện của một trong các tham số của nó, thường thì đây là nơi mã phải được.


Tôi thích câu trả lời này, nhưng bạn có bất kỳ tài liệu tham khảo cập nhật cho điều này? "và thậm chí có thể nhanh hơn một chút"
Magnilex

@Magnilex, Con trỏ "this" không được truyền cho các phương thức lớp tĩnh, do đó chúng sẽ có xu hướng nhanh hơn các phương thức cá thể tĩnh, trừ khi trình biên dịch phát hiện "this" không được sử dụng trong phương thức cá thể (không chắc).
Ian

2

Tôi có thể nghĩ ra ít nhất hai lý do tại sao bạn sẽ cần một phương thức riêng tư tĩnh trên một lớp.

1: Các thể hiện của bạn có lý do để gọi một phương thức tĩnh mà bạn không muốn gọi trực tiếp, có lẽ vì nó chia sẻ dữ liệu giữa tất cả các thể hiện của lớp bạn.

2: Các phương thức tĩnh công khai của bạn có các chương trình con mà bạn không muốn gọi trực tiếp. Phương thức vẫn được gọi mà không có ví dụ, chỉ không trực tiếp.

Tất nhiên, "nó giúp cả lớp có ý nghĩa" là một lý do chính đáng.


1

Nói chung, nếu tôi thấy tôi đang viết các phương thức tĩnh riêng tư, tôi coi đó là một dấu hiệu cho thấy có một cái gì đó tôi nên được mô hình hóa riêng biệt.

Vì chúng không bị ràng buộc với trạng thái của một đối tượng cụ thể, nên một tập hợp các phương thức tĩnh công khai và riêng tư có thể tạo thành một lớp hoàn toàn riêng biệt với các phương thức ngữ nghĩa và không tĩnh riêng của nó.

(Một mẹo khác là nếu tôi thấy tôi có rất nhiều phương thức tĩnh (công khai và riêng tư) mà tất cả đều có một tham số chung của một số loại, chúng có thể tốt hơn khi là thành viên của loại đó.)

Vì vậy, để trả lời câu hỏi của bạn, các phương thức tĩnh riêng xuất hiện khi một lớp cung cấp một nhóm các phương thức liên quan độc lập với một thể hiện của lớp đó. (... Và vì họ độc lập, họ có thể tốt hơn trong lớp của chính họ.)


-1

Ví dụ rất đơn giản tôi có thể nghĩ là, nếu bạn muốn thực hiện một số xử lý trên các đối số đầu vào (hoặc một số thao tác) được truyền cho hàm chính. Vì vậy, trong trường hợp này nếu việc xử lý là lớn và chức năng tương tự sẽ không được sử dụng ở bất kỳ nơi nào khác thì sẽ có chức năng riêng tư vì nó sẽ không được sử dụng / gọi từ bất kỳ nơi nào khác + tĩnh là chính là tĩnh.

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.