Mengapa metode statis hanya menggunakan data statis?
38
Saya tidak mengerti mengapa metode statis tidak dapat menggunakan data non-statis. Adakah yang bisa menjelaskan apa masalahnya dan mengapa kita tidak bisa melakukannya?
Karena hanya data statis yang ada dari sudut pandang metode statis.
mouviciel
4
Berbagi penelitian Anda membantu semua orang. Beri tahu kami apa yang telah Anda coba dan mengapa itu tidak memenuhi kebutuhan Anda. Ini menunjukkan bahwa Anda telah meluangkan waktu untuk mencoba membantu diri sendiri, itu menyelamatkan kami dari mengulangi jawaban yang jelas, dan yang paling utama itu membantu Anda mendapatkan jawaban yang lebih spesifik dan relevan. Lihat juga Cara Meminta
nyamuk
19
@gnat dalam hal ini OP sedang mencoba memahami alasan di balik keputusan desain. Apa yang Anda harapkan dari dia dalam kasus ini?
Geek
2
@ Geek - adanya metode statis, data statis adalah masalah desain bahasa. Dengan asumsi makna standar, fakta bahwa metode statis tidak dapat mengakses data contoh tidak. Keterbatasan tersirat oleh definisi dan apa yang mungkin dan masuk akal, bukan oleh beberapa perancang bahasa kelemahan.
Steve314
6
Mengutip Gertrude Stein: "Tidak ada ini di sana."
penari kuda nil
Jawaban:
73
Di sebagian besar bahasa OO, ketika Anda mendefinisikan metode di dalam kelas, itu menjadi Metode Instance . Saat Anda membuat instance baru dari kelas itu, melalui newkata kunci, Anda menginisialisasi kumpulan data baru yang unik hanya untuk instance itu. Metode milik instance itu kemudian dapat bekerja dengan data yang Anda tetapkan di atasnya.
Metode statis , sebaliknya, tidak mengetahui contoh kelas individu. Metode statis mirip dengan fungsi bebas di C atau C ++. Itu tidak terikat pada Instansiasi khusus kelas. Inilah sebabnya mereka tidak dapat mengakses nilai instance. Tidak ada contoh untuk mengambil nilai dari!
Data Statis mirip dengan metode statis. Nilai yang dideklarasikan statictidak memiliki turunan terkait. Itu ada untuk setiap contoh, dan hanya dinyatakan dalam satu tempat di memori. Jika itu pernah diubah, itu akan berubah untuk setiap instance dari kelas itu.
Sebuah Metode statis dapat mengakses data statis karena mereka berdua ada secara independen dari contoh-contoh spesifik dari kelas.
Mungkin membantu untuk melihat bagaimana Anda menjalankan metode statis, dibandingkan dengan metode contoh. Katakanlah kita memiliki kelas berikut (menggunakan pseudocode Java-like):
classFoo{// This static value belongs to the class Foopublicstaticfinal string name ="Foo";// This non-static value will be unique for every instanceprivateint value;publicFoo(int value){this.value = value;}publicvoid sayValue(){
println("Instance Value: "+ value);}publicstaticvoid sayName(){
println("Static Value: "+ name);}}Foo foo1 =newFoo(10);Foo foo2 =newFoo(20);
foo1.sayValue();// Prints "Instance Value: 10" - called on foo1
foo2.sayValue();// Prints "Instance Value: 20" - called on foo2Foo.sayName();// Prints "Static Value: Foo" - called on Foo (not foo1 or foo2)
Memperbarui
Sebagai DATANG DARI poin di komentar, metode statis adalah mampu bekerja dengan data non-statis, tetapi harus dilalui secara eksplisit. Mari kita asumsikan Fookelas memiliki metode lain:
Addmasih statis, dan tidak memiliki valueturunannya sendiri, tetapi sebagai anggota kelas Foo, ia dapat mengakses valuebidang privat dari pass-in foo1dan foo2turunan. Dalam hal ini, kami menggunakannya untuk mengembalikan yang baruFoo dengan nilai tambah dari kedua nilai yang diteruskan.
Foo foo3 =Foo.Add(foo1, foo2);// creates a new Foo with a value of 30
Memperluas pada "Tidak ada contoh untuk mengambil nilai dari" - bahkan jika ada kasus, metode statis tidak dapat mengetahui mana misalnya untuk mengambil nilai dari.
Steve314
9
Ini jauh lebih rumit untuk dijelaskan dalam bahasa yang tidak memaksa semuanya menjadi bagian dari objek secara default.
Mason Wheeler
3
@Mason Kata-kata yang benar. Bahasa-bahasa seperti Java semacam menegakkan anggapan keliru bahwa suatu fungsi adalah sesuatu yang harus dimiliki kelas.
KChaloux
5
Ini adalah jawaban yang baik tetapi masih gagal untuk mengatakan kebenaran keseluruhan: metode statis dapat mengakses data non-statis. Mereka tidak memiliki objek implisit atau this-referensi yang tersedia. Saya pikir itu sangat penting untuk dipahami.
DATANG DARI
2
@COMEFROM Maksud Anda dengan passing eksplisit? Saya bisa mencatatnya, jika saya mengerti Anda dengan benar. Saya berasumsi itu tersirat bahwa metode statis dapat mengakses secara eksplisit melewati data non-statis, mengingat bahwa setiap fungsi dapat bekerja pada data yang secara eksplisit diteruskan ke sana.
KChaloux
22
Mari kita jelaskan dengan sampel hipotetis.
Bayangkan sebuah kelas sederhana:
classUser{User(string n){ name = n;};
string name;}
sekarang, pikirkan - bagaimana jika kita menambahkan metode statis baru ke Pengguna, misalnya:
static string GetName();
dan Anda menyebutnya:
string x =User::GetName()
apa yang akan berisi x? "Jim", "Bones", atau yang lainnya?
Masalahnya adalah bahwa metode statis adalah metode tunggal, yang didefinisikan pada kelas, bukan objek. Akibatnya, Anda tidak tahu ke objek mana itu mungkin berlaku. Inilah sebabnya mengapa ini hal yang istimewa. Yang terbaik untuk memikirkan metode statis sebagai hal-hal individual, seperti fungsi dalam C misalnya. Bahwa bahasa-bahasa seperti Java mengandungnya di dalam kelas-kelas terutama merupakan masalah dengan Java yang tidak mengizinkan apa pun ada di luar kelas, jadi fungsi-fungsi seperti ini harus dipaksa di dalam suatu kelas dengan cara tertentu (agak seperti bagaimana main () dipaksa menjadi di dalam kelas juga ketika semua akal mengatakan itu harus fungsi tunggal, mandiri).
Itu bisa menggunakan data lapangan; pertimbangkan kode java berikut:
classMyBean{privateString myString;staticvoid myStaticMethod(){
myString ="tada";/*not allowed; if this was possible how would
be different from a field without static?*/MyBean myBean =newMyBean();//allowed if associated with an instance
myBean.myString ="tada";}}
Meskipun ini secara teknis bisa menjadi metode statis menggunakan data non-statis, itu melenceng. Tentu saja Anda dapat membuat instance baru dan mengaksesnya. Tapi itu tidak ada hubungannya sama sekali dengan staticness.
Bobson
2
Sebenarnya, saya pikir ini adalah tambahan yang sangat bagus untuk menjelaskan intinya. Ini menyoroti titik bahwa metode statis membutuhkan turunan kelas sebelum dapat mengakses data non-statis sambil memberikan alasan intuitif mengapa demikian.
Ben Hocking
@ Bobson Anda harus membaca kode dan komentar juga.
m3th0dman
@BenHocking "ya" bahkan saya pikir itu adalah titik yang baik mengatakan bahwa "variabel instan selalu dikaitkan dengan objek"
JAVA
2
Data non-statis dikaitkan dengan turunan kelas. Metode statis (dan data) tidak terkait dengan instance kelas tertentu. Tidak perlu menjadi instance dari kelas untuk menggunakan metode statis di atasnya. Bahkan jika ada instance (s), tidak akan ada cara bagi Java untuk menjamin bahwa Anda beroperasi pada instance yang Anda harapkan ketika Anda memanggil metode statis. Oleh karena itu, metode statis tidak dapat memiliki akses ke data non-statis.
Dari sudut pandang teknis, metode statis yang dipanggil dari dalam suatu objek akan cukup mampu melihat bidang instance. Saya sangat curiga inilah yang menyebabkan pertanyaan itu.
Masalahnya adalah bahwa metode dapat dipanggil dari luar objek. Pada saat itu tidak ada data instance untuk menyediakannya - dan dengan demikian tidak ada cara bagi kompiler untuk menyelesaikan kode. Karena mengizinkan data instan menyebabkan kontradiksi, kita tidak boleh mengizinkan data instan.
Saya tidak setuju. Metode statis tidak dapat mengakses data instance karena data instance harus diakses melalui instance objek dan metode statis tidak terkait dengan instance yang diberikan (tetapi dengan definisi kelas).
Phill W.
Anda melewatkan poin saya. Jika dipanggil dari dalam kelas, kompiler dapat melewatkan sebuah instance pointer seperti ketika tidak kelas statis. Masalahnya muncul jika dipanggil dari tempat lain - yang berarti metode statis privat dapat mengakses data contoh (meskipun secara internal mengabaikan statis.)
Loren Pechtel
Ya, kompiler / bisa / tetapi mengapa harus begitu? Melewati pointer semacam itu pada dasarnya menguranginya menjadi metode instance. Ketentuan Anda bahwa hanya metode pribadi yang dapat melakukan ini diperdebatkan - Teknologi refleksi membuat / semua / metode dapat diakses - pribadi atau tidak - menjadikan ini proposisi yang lebih berisiko. Teman-teman kita di Redmond pergi ke arah lain; bahasa mereka memunculkan peringatan jika Anda mencoba memanggil metode statis terhadap instance objek (dan bukan kelas itu sendiri).
Phill W.
1
Anggap saja sebagai metode statis yang hidup dalam dimensi yang tidak berorientasi objek.
Dalam "dimensi berorientasi objek" suatu kelas dapat menelurkan banyak ego (contoh), setiap ego memiliki hati nurani sendiri melalui kondisinya.
Dalam flat, dimensi non-OO suatu kelas tidak menyadari ego mereka yang hidup dalam dimensi OO. Dunia mereka datar dan prosedural, hampir seolah-olah OOP belum ditemukan, dan seolah-olah kelas adalah program prosedural kecil, dan data statis hanyalah variabel global.
Saya pikir cara termudah untuk menjelaskan ini adalah dengan melihat beberapa kode dan kemudian mempertimbangkan hasil apa yang kita harapkan dihasilkan oleh kode.
// Create three new cars. Cars have a name attribute. Car car1 =newCar("Mazda3");Car car2 =newCar("FordFocus");Car car3 =newCar("HondaFit");// Now we would like to print the names of some cars: // First off why don't we try this: Car.printCarName();// Expected behaviour: // If we think about what we are trying to do here it doesn't// really make sense. What instance of car name should this // print? Should it print Mazda3? FordFoucs?// What is the expected behaviour? If we are going to have a// static call on car call printCarName it should probably do// something like print all car names or a random car name or// throw an error. //Now lets try this instead: Car.printCarName(car1);// Expected Behaviour: // Luckily the expected behaviour is very clear here. This// should print Mazda3. This works as expected. // Finally lets try this:
car1.printMyName();// Expected Behaviour:// Same as previous example, however this is the *right* way// to do it.
Untuk kelengkapan di sini adalah kelas mobil:
publicclassCar{publicString name;publicCar(String name){this.name = name;}publicstatic printCarName(){
print "Not sure what to do here... Don't know which car you are talking about.";}publicstatic printCarName(Car c){
print c.name;}public/*NOT static*/ printMyName(){
print this.name;}}
@gnat Diperbarui dengan komentar untuk diklarifikasi.
sixtyfootersdude
1
Jawaban lain cukup banyak mengatakan itu semua, namun, ada beberapa "detail" yang ingin saya tambahkan.
Metode statis (misalnya yang ada di Jawa) tidak memiliki objek implisit yang terkait dengannya (dapat diakses melalui this) yang anggotanya dapat Anda akses biasanya langsung dengan namanya.
Itu tidak berarti mereka tidak dapat mengakses data non-statis.
classMyClass{publicstaticvoid foo(MyOtherClass object){System.out.println(object.member);}} classMyOtherClass{publicint member =10;}
Saya tahu ini hanya detail, tetapi saya menemukan pertanyaan Anda aneh ketika saya membacanya. "Hanya dapat menggunakan data statis" terlalu ketat.
Ngomong-ngomong, saya tidak menguji kode, saya hanya menulisnya di sini untuk memberikan contoh apa yang saya katakan.
Jawaban:
Di sebagian besar bahasa OO, ketika Anda mendefinisikan metode di dalam kelas, itu menjadi Metode Instance . Saat Anda membuat instance baru dari kelas itu, melalui
new
kata kunci, Anda menginisialisasi kumpulan data baru yang unik hanya untuk instance itu. Metode milik instance itu kemudian dapat bekerja dengan data yang Anda tetapkan di atasnya.Metode statis , sebaliknya, tidak mengetahui contoh kelas individu. Metode statis mirip dengan fungsi bebas di C atau C ++. Itu tidak terikat pada Instansiasi khusus kelas. Inilah sebabnya mereka tidak dapat mengakses nilai instance. Tidak ada contoh untuk mengambil nilai dari!
Data Statis mirip dengan metode statis. Nilai yang dideklarasikan
static
tidak memiliki turunan terkait. Itu ada untuk setiap contoh, dan hanya dinyatakan dalam satu tempat di memori. Jika itu pernah diubah, itu akan berubah untuk setiap instance dari kelas itu.Sebuah Metode statis dapat mengakses data statis karena mereka berdua ada secara independen dari contoh-contoh spesifik dari kelas.
Mungkin membantu untuk melihat bagaimana Anda menjalankan metode statis, dibandingkan dengan metode contoh. Katakanlah kita memiliki kelas berikut (menggunakan pseudocode Java-like):
Memperbarui
Sebagai DATANG DARI poin di komentar, metode statis adalah mampu bekerja dengan data non-statis, tetapi harus dilalui secara eksplisit. Mari kita asumsikan
Foo
kelas memiliki metode lain:Add
masih statis, dan tidak memilikivalue
turunannya sendiri, tetapi sebagai anggota kelas Foo, ia dapat mengaksesvalue
bidang privat dari pass-infoo1
danfoo2
turunan. Dalam hal ini, kami menggunakannya untuk mengembalikan yang baruFoo
dengan nilai tambah dari kedua nilai yang diteruskan.sumber
this
-referensi yang tersedia. Saya pikir itu sangat penting untuk dipahami.Mari kita jelaskan dengan sampel hipotetis.
Bayangkan sebuah kelas sederhana:
Sekarang kita membuat 2 instance dari kelas ini:
sekarang, pikirkan - bagaimana jika kita menambahkan metode statis baru ke Pengguna, misalnya:
dan Anda menyebutnya:
apa yang akan berisi x? "Jim", "Bones", atau yang lainnya?
Masalahnya adalah bahwa metode statis adalah metode tunggal, yang didefinisikan pada kelas, bukan objek. Akibatnya, Anda tidak tahu ke objek mana itu mungkin berlaku. Inilah sebabnya mengapa ini hal yang istimewa. Yang terbaik untuk memikirkan metode statis sebagai hal-hal individual, seperti fungsi dalam C misalnya. Bahwa bahasa-bahasa seperti Java mengandungnya di dalam kelas-kelas terutama merupakan masalah dengan Java yang tidak mengizinkan apa pun ada di luar kelas, jadi fungsi-fungsi seperti ini harus dipaksa di dalam suatu kelas dengan cara tertentu (agak seperti bagaimana main () dipaksa menjadi di dalam kelas juga ketika semua akal mengatakan itu harus fungsi tunggal, mandiri).
sumber
Itu bisa menggunakan data lapangan; pertimbangkan kode java berikut:
sumber
static
ness.Data non-statis dikaitkan dengan turunan kelas. Metode statis (dan data) tidak terkait dengan instance kelas tertentu. Tidak perlu menjadi instance dari kelas untuk menggunakan metode statis di atasnya. Bahkan jika ada instance (s), tidak akan ada cara bagi Java untuk menjamin bahwa Anda beroperasi pada instance yang Anda harapkan ketika Anda memanggil metode statis. Oleh karena itu, metode statis tidak dapat memiliki akses ke data non-statis.
sumber
Saya pikir masalahnya adalah pemahaman.
Dari sudut pandang teknis, metode statis yang dipanggil dari dalam suatu objek akan cukup mampu melihat bidang instance. Saya sangat curiga inilah yang menyebabkan pertanyaan itu.
Masalahnya adalah bahwa metode dapat dipanggil dari luar objek. Pada saat itu tidak ada data instance untuk menyediakannya - dan dengan demikian tidak ada cara bagi kompiler untuk menyelesaikan kode. Karena mengizinkan data instan menyebabkan kontradiksi, kita tidak boleh mengizinkan data instan.
sumber
Anggap saja sebagai metode statis yang hidup dalam dimensi yang tidak berorientasi objek.
Dalam "dimensi berorientasi objek" suatu kelas dapat menelurkan banyak ego (contoh), setiap ego memiliki hati nurani sendiri melalui kondisinya.
Dalam flat, dimensi non-OO suatu kelas tidak menyadari ego mereka yang hidup dalam dimensi OO. Dunia mereka datar dan prosedural, hampir seolah-olah OOP belum ditemukan, dan seolah-olah kelas adalah program prosedural kecil, dan data statis hanyalah variabel global.
sumber
Saya pikir cara termudah untuk menjelaskan ini adalah dengan melihat beberapa kode dan kemudian mempertimbangkan hasil apa yang kita harapkan dihasilkan oleh kode.
Untuk kelengkapan di sini adalah kelas mobil:
sumber
Jawaban lain cukup banyak mengatakan itu semua, namun, ada beberapa "detail" yang ingin saya tambahkan.
Metode statis (misalnya yang ada di Jawa) tidak memiliki objek implisit yang terkait dengannya (dapat diakses melalui
this
) yang anggotanya dapat Anda akses biasanya langsung dengan namanya.Itu tidak berarti mereka tidak dapat mengakses data non-statis.
Saya tahu ini hanya detail, tetapi saya menemukan pertanyaan Anda aneh ketika saya membacanya. "Hanya dapat menggunakan data statis" terlalu ketat.
Ngomong-ngomong, saya tidak menguji kode, saya hanya menulisnya di sini untuk memberikan contoh apa yang saya katakan.
sumber