Mengapa metode statis dianggap sebagai metode?

138

Saya menulis penjelasan untuk beberapa kode untuk kursus, dan secara tidak sengaja menggunakan kata-kata tersebut methoddan functionsecara bergantian. Saya memutuskan untuk kembali dan memperbaiki kata-katanya, tetapi mengalami lubang dalam pemahaman saya.

Dari apa yang saya pahami, subrutin adalah functionjika tidak bertindak pada turunan kelas (efeknya dibatasi pada input / output eksplisitnya), dan methodjika beroperasi pada instance kelas (mungkin membawa efek samping pada contoh yang membuatnya tidak murni).

Ada diskusi bagus di sini tentang topik tersebut. Perhatikan bahwa dengan definisi jawaban yang diterima, statis methodseharusnya menjadi fungsi karena sebuah instance tidak pernah diteruskan secara implisit, dan tidak memiliki akses ke anggota instance mana pun.

Dengan pikiran ini, bukankah seharusnya statis methodsmenjadi fungsi?

Menurut definisi mereka, mereka tidak bertindak atas contoh kelas tertentu; mereka hanya "terikat" dengan kelas karena hubungan. Saya telah melihat beberapa situs berpenampilan bagus yang merujuk pada subrutin statis sebagai "metode" ( Oracle , Fredosaurus , ProgrammingSimplified ), jadi entah mereka semua mengabaikan terminologi, atau saya melewatkan sesuatu (tebakan saya adalah yang terakhir) .

Saya ingin memastikan bahwa saya menggunakan kata-kata yang benar.
Adakah yang bisa membereskan ini?

Carcigenicate
sumber
2
Saya selalu berpikir itu adalah fungsi dalam php dan metode di Jawa. Pada dasarnya hal yang sama dengan nama yang berbeda
JK
20
Ada perbedaan antara ilmu komputer teoretis dan bagaimana bahasa menerapkannya. JLS tidak membedakan dan menyebutnya sebagai metode.
Jeroen Vannevel
2
Ini mungkin menarik untuk melihat pada definisi "fungsi" dan "metode" di Python, di mana ada adalah perbedaan: pada dasarnya, fungsi adalah serangkaian kode dengan tabel simbol dan konvensi memanggil, sedangkan metode adalah apa Anda dapatkan saat Anda memasukkan fungsi ke dalam kelas. Perbedaannya cukup halus, bahkan untuk orang yang mengerti Python.
David Z
2
Ketika saya belajar teori, saya belajar fungsi mengembalikan nilai dan prosedur tidak. Kemudian saya belajar metode fungsi dan prosedur panggilan java. Sekarang saya mencoba programmjng fungsional dan fungsi idempoten. Istilah-istilah tersebut mengubah makna pada konteks.
emory

Jawaban:

125

Kutipan dari 8.4.3.2 ini dapat membantu:

Metode yang dideklarasikan staticdisebut metode kelas .

Metode yang tidak dideklarasikan staticdisebut metode instance [...].

  • Metode kelas: terkait dengan kelas.
  • Metode Instance: terkait dengan sebuah instance.

Java hanya ingin Anda "berpikir berorientasi objek". Selain itu, metode statis memiliki akses ke cakupan sekitarnya yang mungkin mencakup status. Di satu sisi, kelas itu seperti objek itu sendiri.

Radiodef
sumber
Meskipun demikian, sementara "fungsi" secara teknis benar sebagai unit eksekusi di Java, nomenklatur yang disukai di hampir semua Java adalah "metode", karena semua fungsi Java adalah bagian dari kelas atau antarmuka (tidak termasuk lambda, dan mungkin beberapa hal lain yang tidak saya sadari).
Shotgun Ninja
1
Lambdas sebenarnya adalah kelas dalam anonim dengan @FunctionalInterfaceanotasi dan dengan 1 metode di bawah tenda. Lambda hanyalah gula sintaksis dan dalam hal ini tidak ada yang baru.
Adam Arold
1
@AdamArold Lambdas sedikit lebih mewah daripada kelas dalam anonim. Misalnya, lambda yang tidak menangkap bisa berbagi contoh di beberapa evaluasi dari ekspresi tertentu. (Tapi Anda benar, mereka akhirnya dikompilasi ke metode statis dan contoh.)
Radiodef
@Radiodef Mungkin cara yang lebih baik untuk mengucapkannya adalah "Semua ekspresi lambda dapat diganti dengan ekspresi non-lambda yang setara, tanpa membuat perubahan apa pun pada file selain yang berisi ekspresi lambda" atau sesuatu seperti itu.
pengguna253751
4
Aku malu. Saya berasal dari Scala dan masih berhasil melewatkan fakta bahwa kelas itu sendiri adalah seperti objek. Terima kasih.
Carcigenicate
80

Jawaban sederhananya adalah ketika Java memutuskan untuk menyebut semuanya sebagai "metode", mereka tidak peduli tentang perbedaan antara fungsi dan metode dalam ilmu komputer teoretis.

Bitcoin M
sumber
3
Betul sekali. Sampai dan termasuk Java 7 Anda bahkan tidak akan menemukan kata "fungsi" dalam Spesifikasi Bahasa
Erwin Bolwidt
4
Meskipun saya menyukai kesederhanaan jawaban ini, saya pikir jawaban Radiodef lebih tepat karena menyebutkan poin kunci bahwa kelas itu sendiri bertindak sebagai objek. Terima kasih.
Carcigenicate
2
Menariknya, ini paralel dengan keputusan bahasa sebelumnya untuk tidak membedakan antara fungsi dan subrutin.
Random832
4
Saya terkejut dan tidak menyenangkan bahwa jawaban ini mendapat begitu banyak suara positif. Pertama, jawaban ini berpura-pura bahwa metode kelas tidak ada. Kedua, ini bukanlah konsep yang diperkenalkan di Jawa. Metode kelas sudah ada di Smalltalk, misalnya, yang sudah ada selama beberapa dekade sebelum Java menjadi sesuatu.
Malcolm
1
@Malcolm Saya harus setuju dengan Anda. Setelah mempertimbangkan jawaban lainnya, ini sepertinya salah. Itu bukan sikap apatis di pihak pembuat Java, kecuali mereka benar-benar tidak peduli tetapi akhirnya menamainya dengan benar.
Carcigenicate
26

Metode statis bukanlah fungsi yang tepat, perbedaannya halus, tetapi penting.

Metode statis yang hanya menggunakan parameter masukan yang diberikan pada dasarnya adalah sebuah fungsi.

Tetapi metode statis dapat mengakses variabel statis dan fungsi statis lainnya (juga menggunakan variabel statis) sehingga metode statis dapat memiliki status yang secara fundamental berbeda dengan fungsi yang menurut definisi stateless . (TAMBAHAN: Meskipun programmer sering tidak terlalu ketat dalam menggunakan "fungsi" sebagai definisi, fungsi ketat dalam ilmu komputer hanya dapat mengakses parameter input). Jadi mendefinisikan kasus mengakses bidang statis ini, tidak valid untuk mengatakan bahwa metode statis selalu berfungsi.

Perbedaan lain yang membenarkan penggunaan "metode statis" adalah Anda dapat mendefinisikan dalam C turunan fungsi global dan variabel global yang dapat diakses di mana saja. Jika Anda tidak dapat mengakses kelas yang berisi metode statis, metode tersebut juga tidak dapat diakses. Jadi "metode statis" dibatasi dalam ruang lingkupnya dengan desain berbeda dengan fungsi global.

Thorsten S.
sumber
2
Saya menyukai jawaban ini, tetapi ingin lebih memahami beberapa hal. Bukankah ini lebih merupakan fungsi "murni" vs "efek samping", daripada fungsi vs metode? Atau apakah suatu metode seperti itu karena efek samping? Saya baru saja melakukan brainstorming di sini.
Nadir Sampaoli
2
Jawabannya benar. Namun, orang dapat berargumen bahwa fungsi dalam banyak (sebagian besar?) Bahasa dapat mengakses variabel global, sehingga seringkali tidak sepenuhnya stateless (input yang sama, output yang sama). Dan dalam kasus metode statis Java, untuk mengakses variabel kelas dapat dianggap setara dengan mengakses variabel "global" (yaitu bukan lokal ke fungsi / metode) - dengan instance kelas semacam namespace.
leonbloy
1
@leonbloy Bahasa pemrograman Fungsional Murni seperti Haskell sepenuhnya tanpa kewarganegaraan; tidak ada yang bisa disebut variabel global.
Thorsten S.
17

Di Java, kelas yang ditentukan pengguna sebenarnya adalah turunan dari subkelas java.lang.Class.

Dalam hal ini, metode statis yang melekat pada sebuah instance dari kelas konseptual: mereka melekat ke sebuah contoh dari subclass dari java.lang.Class.

Dengan pemikiran ini, istilah "metode kelas" (nama alternatif untuk metode statis Java) mulai masuk akal. Dan istilah "metode kelas" dapat ditemukan di banyak tempat: Objective C, Smalltalk, dan JLS - untuk menyebutkan beberapa saja.

Mike Clark
sumber
Apakah mungkin untuk memiliki dua contoh subkelas ini?
Random832
Tentu saja, Anda dapat memuat kelas di classloader yang berbeda (alasan mendapatkan ClassCastExceptions dengan pesan "tidak dapat mentransmisikan CustomClass ke CustomClass").
dunni
2
@ Random832 - semacam. Anda dapat memiliki dua (atau lebih) instance dari subclass Class yang sama dalam JVM yang sama, selama setiap instance memiliki classloader terpisah. Anda tidak dapat membuat instance subclass Class yang sama lebih dari sekali per classloader. Ini menjadi sedikit membingungkan dan analogi dengan konsep OO klasik mulai sedikit melebar pada saat ini.
Mike Clark
@MikeClark jika saya melakukan itu, apakah mereka benar - benar sama? Seperti, apakah subkelas Kelas akan menjadi kelas yang sama meskipun kelas itu sendiri adalah instance yang berbeda? Classloader cukup membingungkan saya. Bisakah saya memanggil (tanpa refleksi) metode statis dari satu instance classloader dari sebuah kelas dari instance classloader lain dari kelas yang sama, dengan referensi ke itu diteruskan? Bagaimana jika mereka memiliki metode yang berbeda?
Random832
1
@ Random832 "Semacam?" Dari sudut pandang teori OO murni, apakah ada dua contoh kelas yang benar- benar sama? Setidaknya dua contoh identik dari kelas yang sama akan memiliki alamat yang berbeda. Jika tidak, bagaimana kita bisa memiliki dua hal? Satu-satunya hal yang persis sama dengan sesuatu, adalah benda itu sendiri.
Mike Clark
11

Dalam fungsi ilmu komputer dengan jelas memetakan ke metode statis. Tapi "metode" kelas agak umum, seperti "anggota" (anggota lapangan, anggota metode). Ada kata-kata seperti

Anggota data dan anggota metode memiliki dua ruang nama terpisah: .x dan .x () dapat hidup berdampingan.

Jadi alasannya, seperti yang dikatakan oleh filosof Ludwig Wittgenstein, Bahasa adalah alat dengan konteks yang berbeda. "Metode" adalah moniker yang bagus dalam kutipan di atas untuk mengkategorikan "anggota".

Joop Eggen
sumber
9

Pemikiran Anda benar dan masuk akal. Hanya saja terminologi belum mapan di masyarakat Jawa. Izinkan saya menjelaskan beberapa internal yang dapat membantu memahami mengapa terminologi itu ada.

Java adalah bahasa berorientasi objek berbasis kelas. Metode selalu menjadi anggota kelas atau instance (Ini adalah pernyataan umum yang juga berlaku untuk bahasa pemrograman lain). Kami memikirkan kelas dan instance sebagai kedua objek.

Metode instance (dinamis)

Anda tidak dapat memanggil metode ini dari kelas secara langsung, Anda harus membuat sebuah instance. Setiap contoh mereferensikan metode itu. Anda dapat menimpa definisi metode dengan tanda tangan metode yang sama persis (saat membuat subclass), yaitu referensi menunjuk ke metode yang berbeda (yang memiliki tanda tangan yang sama, tetapi dapat memiliki badan metode yang berbeda). Metodenya dinamis.

Metode kelas (statis)

Anda hanya dapat memanggil metode ini dari kelas secara langsung, misalnya Anda tidak perlu membuat turunan dari kelas itu. Hanya ada satu definisi global dari metode itu di seluruh program. Anda tidak dapat menimpa tanda tangan metode yang sama persis jika metode tersebut dinyatakan statis, karena hanya ada satu definisi yang valid untuk keseluruhan program. Perhatikan bahwa metode ini adalah anggota dari objek kelas itu sendiri, semua instance memiliki referensi unik (dan perbaikan) yang sama ke metode itu.

Ely
sumber
7

Berikut adalah pandangan lain tentang terminologi, menggunakan Scala sebagai mnemonik:
Di Scala Anda memiliki objects, yang merupakan instance tunggal dari kelas yang didefinisikan secara implisit1 .

Sesuai definisi Anda, kami dapat memanggil subrutin ini milik object metode , karena mereka beroperasi pada satu instance kelas.
Selain itu objek juga akan mendefinisikan kelas A, dan membuat semua metode di objek A sebagai metode statis pada kelas A (untuk berinteraksi dengan Java) [2] .

Oleh karena itu kita dapat mengatakan bahwa metode statis kelas A Java mengakses anggota yang sama dengan instance tunggal Scala, yang menurut definisi Anda layak disebut metode (statis) kelas A.

mucaho
sumber
Perbandingan yang bagus. Saya tahu Scala, jadi objectreferensi Anda sangat masuk akal. Terima kasih.
Carcigenicate
2

Tentu saja, perbedaan utamanya adalah - metode dapat menggunakan bidang statis, tidak hanya parameter metode. Tetapi ada satu tambahan - polimorfisme! Hasil evaluasi Kelas A. doTheSameStaticMethod () dan ClassB.doTheSameStaticMehod () akan bergantung pada kelas. Dalam hal ini fungsinya tidak berdaya.

Павел Бивойно
sumber
1

Setiap kelas memiliki objek untuk mewakilinya yang merupakan turunan dari subkelas Classkelas. Metode statis sebenarnya adalah metode contoh pada objek ini yang merupakan turunan dari subkelas Kelas. Mereka memiliki akses ke status dalam bentuk bidang statis, jadi mereka tidak terbatas hanya pada fungsi (tanpa negara). Itu adalah metode.

Bohemian
sumber