Tại sao việc truyền đối tượng qua các phương thức tĩnh sẽ thuận lợi?


9

Tại sao có một lợi thế để sử dụng một phương thức tĩnh và truyền tham chiếu đến một đối tượng làm tham số thay vì gọi phương thức trên một đối tượng?

Để làm rõ những gì tôi muốn nói, hãy xem xét các lớp sau:

public class SomeClass {
    private double someValue;

    public SomeClass() {
        // Some constructor in which someValue is set
    }

    public void incrementValue() {
        someValue++;
    }
}

So với thực hiện thay thế này với một phương thức tĩnh:

public class SomeClass {
    private double someValue;

    public SomeClass() {
        // Some constructor in which someValue is set
    }

    public static void incrementValue(SomeClass obj) {
        obj.someValue++;
    }
}

Câu hỏi của tôi không chỉ giới hạn trong lớp học này; bất kỳ điểm nào mà bạn vượt qua một đối tượng thay vì gọi nó trên một phương thức là điều tôi quan tâm. Điều này có thuận lợi không? Nếu vậy, tại sao?


1
Cảm giác giống như một mùi mã với hai phương thức thực hiện chính xác cùng một điều. Nếu phương thức tĩnh được ủy thác đơn giản cho phương thức kia, thì nó sẽ cảm thấy vô dụng, nhưng không nhất thiết là "xấu"
Nathan Merrill

13
@NathanMerrill Tôi nghĩ bạn đang thiếu điểm. Anh ấy hỏi liệu có bao giờ tình huống tạo và sử dụng phương pháp thứ hai thay vì phương pháp thứ nhất sẽ tốt hơn không.

@Mego Không chỉ các phương thức được đưa ra trong ví dụ; Tôi đang hỏi liệu có bất kỳ lúc nào khi sử dụng các phương thức tĩnh và truyền các đối tượng tốt hơn so với việc gọi các phương thức trên các đối tượng không?
Addison Crump

Có lẽ bạn đang hỏi cụ thể cho java?
thúc

3
Tôi nghĩ rằng câu hỏi này đưa ra một giả định ngầm rằng mã hướng đối tượng là một loại tối ưu. Một cách tiếp cận theo thủ tục hoặc chức năng hơn đương nhiên sẽ dẫn đến việc sử dụng các phương thức tĩnh. ... Mặc dù, việc sao chép chức năng giữa một phương thức tĩnh và phương thức khá là ngớ ngẩn. Tôi hy vọng đó chỉ là một ví dụ và mã thực tế mà bạn đang nói chỉ có tĩnh.
jpmc26

Câu trả lời:


34

Một ví dụ tầm thường: khi cá thể được thông qua có thể là null và bạn muốn kết hợp xử lý (không tầm thường) của phương thức này vào phương thức.


1
ví dụ: String.Compare trong C # (Tôi nghĩ có một cái gì đó tương tự trong Java)
edc65

Object.equals () và Object.compare () là các ví dụ trong Java - nhưng chúng không có trên lớp gốc. Trong các tiêu chuẩn Java thư viện ít nhất, đó là phổ biến để có một phương pháp dụ về một cái gì đó giống như đối tượng, nhưng sau đó một phương pháp tĩnh trên một Object s lớp.
daboross 12/03/2016

20

Trong ví dụ của bạn, phương thức ví dụ là một người chiến thắng rõ ràng.

Trong trường hợp chung, tôi có thể nghĩ ra một vài lý do trong đó một phương thức tĩnh có thể phù hợp:

  • Bạn muốn đặt phương thức tĩnh trong một lớp khác, vì bạn có một tình huống hợp lý để tách logic khỏi dữ liệu (lưu ý: ví dụ của bạn không phải là một trong số chúng).

  • Bạn đang vượt qua hai hoặc nhiều đối tượng và muốn nhấn mạnh rằng chúng có tầm quan trọng như nhau.

  • null là một giá trị hợp lệ (như được giải thích bởi người dùng 9000).


5

Nó sẽ là khôn ngoan để bao gồm các phương pháp mà thay đổi trạng thái của đối tượng như ví dụ phương pháp chứ không phải là tĩnh phương pháp.

Tuy nhiên, chúng ta có thể tìm thấy các ví dụ về các phương thức tĩnh là purecác phương thức và lấy đối tượng làm đầu vào, giống như khi chúng ta cần khởi tạo đối tượng dựa trên các quy tắc xác thực nhất định. Ví dụ, .NET có phương thức DateTime.TryParse(String s, DateTime d)để xác nhận và khởi tạo đối tượng. Nhưng tham số DateTime dđược đánh dấu rõ ràng là out.

Một trường hợp khác có thể là khi chúng ta so sánh các đối tượng và muốn lấy đối tượng mong muốn làm giá trị trả về thay vì giá trị boolean / số nguyên của kết quả so sánh, ví dụ , Team.GetHigherScorer(teamA, teamB).IncreaseRanking(). Điều này sẽ sạch hơn:

int compareResult = teamA.compareScoreWith(teamB);
if (compareResult == 1)
    teamA.IncreaseRanking();
else if (compareResult == -1) 
    teamB.IncreaseRanking();

(để lại trường hợp "vẽ" ra cho đơn giản).


1
Một người không vượt qua một "toàn bộ đối tượng". Bạn chuyển tham chiếu đến một vị trí trong bộ nhớ, đó là một lượng rất nhỏ dữ liệu được truyền. Tôi không chắc chắn về ảnh hưởng đến hiệu suất có, nhưng tuy nhiên ... ngoài ra, việc đánh dấu "ra" có ý nghĩa gì?
Addison Crump

1
Tôi bỏ từ 'toàn bộ' từ tuyên bố của mình, nó thật khó hiểu. Tôi không bao giờ có ý định hiệu suất hoặc kích thước, câu trả lời hoàn toàn dựa trên thực tiễn lập trình. Dù sao, outlà một .Nettừ khóa được sử dụng như một sửa đổi tham số. Nó nói rằng tham số được truyền bằng tham chiếu. Xem để biết chi tiết msdn.microsoft.com/en-us/l
Library / t3c3bfhx.aspx

4
Câu đầu tiên đơn giản là sai. nếu chúng ta có class C { int x; static void M() { thì M hoàn toàn có thể truy cập x. Ví dụ int y = (new C()).x;là hợp pháp.
Eric Lippert

@EricLippert :) Tôi chắc chắn bạn biết ý tôi là gì. Thật đáng kinh ngạc khi các bậc thầy có thể đọc giữa các dòng. Có thể tôi cần chỉnh sửa câu đó. Để làm rõ, một cái gì đó như thế này static void M() { this.x = 1; }là không thể.
wonderbell

1
@wonderbell: Không, tôi chắc chắn tôi không biết ý của bạn là gì. Tôi biết những gì bạn đã viết. Tôi lưu ý rằng đó this.xlà sai không phải vì xkhông thể truy cập mà vì thiskhông tồn tại. Đó không phải là một câu hỏi về quyền truy cập , đó là câu hỏi về sự tồn tại .
Eric Lippert

4

Dependency Injection sẽ là một lý do tốt để thực hiện cuộc gọi đến phương thức tĩnh. Giả sử rằng việc thực hiện cụ thể SomeClasscó một chuỗi thừa kế hoặc là việc thực hiện một lớp khác. Bạn có thể sử dụng một giả của một đối tượng, vượt qua nó cho mục đích thử nghiệm để đảm bảo rằng phương thức của bạn thực hiện đúng những gì nó được yêu cầu và sau đó báo cáo về trạng thái đó.

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.