Saya tidak mengerti mengapa metode statis tidak dapat menggunakan data non-statis. Adakah yang bisa menjelaskan apa masalahnya dan mengapa kita tidak bisa melakukannya?
Saya tidak mengerti mengapa metode statis tidak dapat menggunakan data non-statis. Adakah yang bisa menjelaskan apa masalahnya dan mengapa kita tidak bisa melakukannya?
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):
class Foo {
// This static value belongs to the class Foo
public static final string name = "Foo";
// This non-static value will be unique for every instance
private int value;
public Foo(int value) {
this.value = value;
}
public void sayValue() {
println("Instance Value: " + value);
}
public static void sayName() {
println("Static Value: " + name);
}
}
Foo foo1 = new Foo(10);
Foo foo2 = new Foo(20);
foo1.sayValue(); // Prints "Instance Value: 10" - called on foo1
foo2.sayValue(); // Prints "Instance Value: 20" - called on foo2
Foo.sayName(); // Prints "Static Value: Foo" - called on Foo (not foo1 or foo2)
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:
public static Foo Add(Foo foo1, Foo foo2) {
return new Foo(foo1.value + foo2.value);
}
Add
masih statis, dan tidak memiliki value
turunannya sendiri, tetapi sebagai anggota kelas Foo, ia dapat mengakses value
bidang privat dari pass-in foo1
dan foo2
turunan. Dalam hal ini, kami menggunakannya untuk mengembalikan yang baru Foo
dengan nilai tambah dari kedua nilai yang diteruskan.
Foo foo3 = Foo.Add(foo1, foo2); // creates a new Foo with a value of 30
this
-referensi yang tersedia. Saya pikir itu sangat penting untuk dipahami.
Mari kita jelaskan dengan sampel hipotetis.
Bayangkan sebuah kelas sederhana:
class User
{
User(string n) { name = n; };
string name;
}
Sekarang kita membuat 2 instance dari kelas ini:
User Bones = new User("Bones");
User Jim = new User("Jim");
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:
class MyBean {
private String myString;
static void myStaticMethod() {
myString = "tada";/*not allowed; if this was possible how would
be different from a field without static?*/
MyBean myBean = new MyBean();//allowed if associated with an instance
myBean.myString = "tada";
}
}
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.
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.
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 = new Car("Mazda3");
Car car2 = new Car("FordFocus");
Car car3 = new Car("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:
public class Car{
public String name;
public Car(String name){
this.name = name;
}
public static printCarName(){
print "Not sure what to do here... Don't know which car you are talking about.";
}
public static printCarName(Car c){
print c.name;
}
public /*NOT static*/ printMyName(){
print this.name;
}
}
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.
class MyClass {
public static void foo(MyOtherClass object) {
System.out.println(object.member);
}
}
class MyOtherClass {
public int 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.