Mengapa melewatkan objek melalui metode statis akan menguntungkan?

9

Mengapa ada keuntungan menggunakan metode statis dan meneruskan referensi ke objek sebagai parameter daripada memanggil metode pada objek?

Untuk memperjelas apa yang saya maksud, pertimbangkan kelas berikut:

public class SomeClass {
    private double someValue;

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

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

Dibandingkan dengan penerapan alternatif ini dengan metode statis:

public class SomeClass {
    private double someValue;

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

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

Pertanyaan saya tidak terbatas pada kelas ini saja; setiap titik di mana Anda akan melewati objek alih-alih menyebutnya dengan metode adalah hal yang saya minati. Apakah ini pernah menguntungkan? Jika demikian, mengapa?

Addison Crump
sumber
1
Rasanya seperti bau kode dengan dua metode melakukan hal yang persis sama. Jika metode statis hanya didelegasikan ke metode lain, maka itu akan terasa tidak berguna, tetapi tidak selalu "buruk"
Nathan Merrill
13
@NathanMerrill Saya pikir Anda tidak mengerti intinya. Dia bertanya apakah pernah ada situasi di mana membuat dan menggunakan metode kedua alih-alih metode pertama akan lebih disukai.
@Mego Tidak hanya metode yang diberikan dalam contoh; Aku bertanya apakah ada setiap saat ketika menggunakan metode statis dan melewati objek lebih baik daripada memanggil metode pada objek?
Addison Crump
Mungkin Anda bertanya secara khusus untuk java?
enderland
3
Saya pikir pertanyaan ini membuat asumsi diam-diam bahwa kode berorientasi objek adalah semacam optimal. Pendekatan yang lebih prosedural atau fungsional secara alami akan mengarah pada penggunaan metode statis. ... Menggandakan fungsi antara metode statis dan contoh cukup konyol. Saya harap itu hanya contoh dan kode aktual yang Anda bicarakan hanya memiliki statis.
jpmc26

Jawaban:

34

Contoh sepele: ketika instance dilewatkan dapat menjadi nol dan Anda ingin memasukkan penanganan (non-sepele) ini ke dalam metode.

9000
sumber
1
contoh: String.Compare dalam C # (saya pikir ada sesuatu yang serupa di Jawa)
edc65
Objects.equals () dan Objects.compare () adalah contoh di Jawa - tetapi mereka tidak ada di kelas asli. Dalam Java perpustakaan standar setidaknya, itu umum untuk memiliki metode contoh pada sesuatu seperti Object, tapi kemudian metode statis pada Object s kelas.
daboross
20

Dalam contoh Anda, metode instance adalah pemenang yang jelas.

Dalam kasus umum, saya dapat memikirkan beberapa alasan di mana metode statis mungkin sesuai:

  • Anda ingin meletakkan metode statis di kelas lain, karena Anda memiliki situasi di mana masuk akal untuk memisahkan logika dari data (catatan: contoh Anda bukan salah satunya).

  • Anda melewati dua atau lebih objek dan ingin menekankan bahwa mereka sama pentingnya.

  • null adalah nilai yang valid (seperti yang dijelaskan oleh pengguna 9000).

Heinzi
sumber
5

Akan lebih bijaksana untuk memasukkan metode yang mengubah keadaan objek sebagai metode instance daripada metode statis .

Namun kita dapat menemukan contoh metode statis yang merupakan puremetode dan mengambil objek sebagai input, seperti ketika kita perlu instantiate objek berdasarkan aturan validasi tertentu. Misalnya, .NET memiliki metode DateTime.TryParse(String s, DateTime d)untuk memvalidasi dan membuat instance objek. Tetapi parameter DateTime dsecara eksplisit ditandai sebagai out.

Kasus lain dapat terjadi ketika kita membandingkan objek dan ingin mendapatkan objek yang diinginkan sebagai nilai balik daripada nilai boolean / integer dari hasil perbandingan, misalnya Team.GetHigherScorer(teamA, teamB).IncreaseRanking(),. Ini akan lebih bersih daripada:

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

(meninggalkan case "menarik" untuk kesederhanaan).

keajaiban
sumber
1
Seseorang tidak melewati "seluruh objek". Anda meneruskan referensi ke tempat di memori, yang merupakan jumlah data yang sangat kecil yang dilewatkan. Saya tidak yakin tentang pengaruhnya terhadap kinerja yang telah terjadi, tetapi meskipun demikian ... juga, apa yang tersirat dari tanda "keluar" itu?
Addison Crump
1
Saya menjatuhkan kata 'keseluruhan' dari pernyataan saya, itu membingungkan. Saya tidak pernah bermaksud kinerja atau ukuran, jawabannya murni berdasarkan praktik pemrograman. Bagaimanapun, outadalah .Netkata kunci yang digunakan sebagai pengubah parameter. Ini menyatakan bahwa parameter dilewatkan oleh referensi. Lihat untuk detail msdn.microsoft.com/en-us/library/t3c3bfhx.aspx
wonderbell
4
Kalimat pertama benar-benar salah. jika sudah, class C { int x; static void M() { maka M dapat diakses dengan sempurna x. Misalnya int y = (new C()).x;legal.
Eric Lippert
@EricLippert :) Saya yakin Anda tahu apa yang saya maksud. Sungguh menakjubkan bagaimana para master dapat membaca yang tersirat. Mungkin saya perlu mengedit kalimat itu. Untuk klarifikasi, hal seperti ini static void M() { this.x = 1; }tidak mungkin.
wonderbell
1
@wonderbell: Tidak, saya yakin saya tidak tahu apa yang Anda maksud. Saya tahu apa yang Anda tulis. Saya perhatikan itu this.xsalah bukan karena xtidak dapat diakses tetapi karena thistidak ada. Ini bukan masalah akses sama sekali, ini masalah keberadaan .
Eric Lippert
4

Ketergantungan Injeksi akan menjadi alasan yang baik untuk melakukan panggilan ke metode statis. Dengan asumsi bahwa implementasi konkret SomeClassmemiliki rantai warisan atau implementasi dari kelas lain. Anda dapat menggunakan tiruan dari suatu objek, meneruskannya untuk tujuan pengujian untuk memastikan bahwa metode Anda melakukan apa yang seharusnya, dan kemudian melaporkan status itu.

Adam Zuckerman
sumber