Statik bir yöntemin neden statik olmayan verileri kullanamadığını anlamıyorum. Sorunların ne olduğunu ve neden yapamadığımızı açıklayabilen var mı?
Statik bir yöntemin neden statik olmayan verileri kullanamadığını anlamıyorum. Sorunların ne olduğunu ve neden yapamadığımızı açıklayabilen var mı?
Yanıtlar:
Çoğu OO dilinde, bir sınıf içinde bir yöntem tanımladığınızda, bir Örnek Yöntemi olur . Bu sınıfın yeni bir örneğini oluşturduğunuzda , newanahtar kelime aracılığıyla, yalnızca bu örneğe özgü yeni bir veri kümesi başlatırsınız. Bu örneğe ait yöntemler daha sonra üzerinde tanımladığınız verilerle çalışabilir.
Statik Yöntemler , aksine, bireysel sınıf örnekleri görmezden geliyor. Statik yöntem, C veya C ++ 'da serbest bir işleve benzer. Sınıfın belirli bir örneğine bağlı değildir. Bu yüzden örnek değerlerine erişemezler. Bir değer almak için bir örnek yok!
Statik Veri , statik bir yönteme benzer. Bildirilen bir değerin staticilişkili bir örneği yoktur. Her örnek için var ve yalnızca bellekte tek bir yerde bildiriliyor. Eğer hiç değişmezse, o sınıfın her bir örneği için değişecek.
Bir statik metot erişebilir Statik Veri her ikisi de bir sınıf belirli örnekleri arasında bağımsız bir şekilde, mevcut olduğundan.
Örnek bir yönteme kıyasla, statik bir yöntemi nasıl çağırdığınıza bakmanıza yardımcı olabilir. Diyelim ki şu sınıfa sahibiz (Java benzeri sözde kod kullanarak):
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)
As GELMEKTEDİR Açıklamalarda noktaları, statik bir yöntem olan statik olmayan verilerle çalışabilir, ancak açıkça geçirilmelidir. FooSınıfın başka bir yöntemi olduğunu varsayalım :
public static Foo Add(Foo foo1, Foo foo2) {
return new Foo(foo1.value + foo2.value);
}
Addhala durağandır ve kendine ait hiçbir valueörneği yoktur , ancak Foo sınıfının bir üyesi olarak, girilenlerin ve örneklerin özel valuealanlarına erişebilir . Bu durumda, bir döndürecek şekilde kullanıyoruz yeni hem katma değerlerle geçti-değerleri.foo1foo2 Foo
Foo foo3 = Foo.Add(foo1, foo2); // creates a new Foo with a value of 30
thisuygunluğa sahip değiller. Bunun anlaşılması için hayati derecede önemli olduğunu düşünüyorum.
Varsayımsal bir örnekle açıklayalım.
Basit bir sınıf düşünün:
class User
{
User(string n) { name = n; };
string name;
}
Şimdi bu sınıfın 2 örneğini yaratıyoruz:
User Bones = new User("Bones");
User Jim = new User("Jim");
Şimdi düşünün - Kullanıcıya yeni bir statik yöntem eklersek, örneğin:
static string GetName();
ve sen buna diyorsun:
string x = User::GetName()
x ne içerir? "Jim", "Bones" ya da başka bir şey?
Sorun statik bir yöntemin sınıfta tanımlanan, nesneler değil tek bir yöntem olmasıdır. Sonuç olarak, hangi nesneye uygulanabileceğini bilmiyorsunuz. Bu yüzden özel bir şey. Statik yöntemleri tek tek şeyler olarak düşünmek en iyisidir, örneğin C'deki işlevler gibi. Java gibi dillerin sınıf içerisinde içerdiği Java'nın sınıfla ilgili hiçbir şeyin bulunmasına izin vermemesi gibi bir problem olduğu için, bunun gibi fonksiyonların bir sınıf içinde bir şekilde zorlanması gerekir (biraz main () gibi olması zorunludur) Bir sınıf içinde, her anlamda bir tekil, bağımsız işlev olması gerektiğini söylediğinde.
Statik olmayan veriler sınıfın bir örneğiyle ilişkilendirilir. Statik yöntemler (ve veriler) sınıfın belirli bir örneği ile ilişkili değildir. Üzerinde statik yöntemler kullanmak için bir sınıf örneği olması gerekmez. Örnek (ler) olsa bile, Java'nın statik bir yöntem çağırırken beklediğiniz örnek üzerinde çalıştığınızı garanti etmesinin bir yolu olmazdı. Bu nedenle, statik yöntemler statik olmayan verilere erişemez.
Alan verilerini kullanabilir; aşağıdaki java kodunu göz önünde bulundurun:
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";
}
}
staticNess ile hiçbir ilgisi yok .
Buradaki meselenin bir anlayış olduğunu düşünüyorum.
Teknik açıdan bakıldığında, bir nesnenin içinden çağrılan statik bir yöntem, örnek alanlarını görmede oldukça yetenekli olacaktır. Soruya en çok neden olan şey bu olduğundan şüpheleniyorum.
Mesele şu ki, yöntemler nesnenin dışından çağrılabilir. Bu noktada, onlara verilecek hiçbir örnek veri yoktur - ve böylece derleyicinin kodu çözmesi mümkün değildir. Örnek verilere izin vermek bir çelişki oluşturduğundan, örnek verilere izin vermemeliyiz.
Nesne yönelimli olmayan bir boyutta yaşayan statik yöntemler olarak düşünün.
"Nesne yönelimli boyutta" bir sınıf, çoklu egoları (örnekler) ortaya koyabilir, her ego, kendi devleti aracılığıyla kendi vicdanına sahiptir.
Düz olmayan, OO boyutunda olmayan bir sınıf, OO boyutunda yaşayan egolarından habersizdir. Dünyaları, neredeyse OOP henüz icat edilmemiş ve sınıf küçük bir prosedür programı gibiydi ve statik veriler de sadece küresel değişkenlermiş gibi düz ve yordamsaldır.
Bunu açıklamanın en kolay yolunun bir koda bakmak ve ardından kodun üretmesini bekleyeceğimiz sonuçları düşünmek olduğunu düşünüyorum.
// 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.
Burada bütünlüğü için araba sınıfı:
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;
}
}
Diğer cevaplar hemen hemen her şeyi söylüyor, ancak eklemek istediğim bazı "ayrıntılar" var.
Statik yöntemler (Java'dakileri söyleyin this), üyelerine genellikle doğrudan adlarıyla erişebileceğiniz, kendisiyle ilişkilendirilmiş (erişilebilir ) ilişkili, gizli bir nesneye sahip değilsiniz .
Bu, statik olmayan verilere erişemeyecekleri anlamına gelmez.
class MyClass {
public static void foo(MyOtherClass object) {
System.out.println(object.member);
}
}
class MyOtherClass {
public int member = 10;
}
Bunun sadece bir detay olduğunu biliyorum ama sorunuzu okuduğumda garip buldum. "Yalnızca statik verileri kullanabilir" çok kısıtlayıcı.
Bu arada, kodu test etmedim, sadece söylediklerimi örneklemek için buraya yazdım.