Statik yöntemler neden yalnızca statik verileri kullanabilir?


38

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ı?


11
Çünkü statik yöntemler açısından sadece statik veriler bulunmaktadır.
mouviciel

4
Araştırmanızı paylaşmak herkese yardımcı olur. Bize ne denediğinizi ve neden ihtiyaçlarınızı karşılamadığını söyleyin. Bu, kendinize yardım etmek için zaman harcadığınızı, bariz cevapları tekrar etmemizi önlediğini ve hepsinden daha belirgin ve alakalı bir cevap almanıza yardımcı olduğunu gösteriyor. Ayrıca Nasıl
Sorulur

19
@ Bu durumda OP, bir tasarım kararının arkasındaki nedeni anlamaya çalışıyor. Bu durumda ne denemesini bekliyorsunuz?
Geek

2
@Geek - Statik yöntemlerin varlığı, statik veri bir dil tasarım konusudur. Standart anlamları varsayarak, statik yöntemlerin örnek verilere erişemediği gerçeği değildir. Sınırlama, bazı dil tasarımcılarının fobileri tarafından değil, tanımları ve neyin mümkün olduğunu ve ne anlama geldiğini ima eder.
Steve314 11:13

6
Gertrude Stein aktaracak olursak: "Hayır yok bu var."
suaygırı-dansçı

Yanıtlar:


73

Ç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)

Güncelleme

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

30
"Değer almak için bir örnek yok" u genişleterek - örnekler olsa bile, statik yöntem hangi örneğin bir değer alacağını bilemez .
Steve314 11:13

9
Bu, varsayılan olarak her şeyi bir nesnenin parçası olmaya zorlamayan dillerde açıklamak için çok daha az karmaşıktır.
Mason Wheeler

3
@Mason Gerçek kelimeler. Java gibi diller, bir işlevin mutlaka bir sınıfa ait olduğu konusunda yanlış bir fikre zorlar.
KChaloux

5
Bu güzel bir cevaptır ama yine de bütün gerçeği anlatmak için başarısız: statik yöntemler olabilir statik olmayan verilere erişmek. Sadece örtük bir nesneye veya thisuygunluğa sahip değiller. Bunun anlaşılması için hayati derecede önemli olduğunu düşünüyorum.
GELMEKTEDİR

2
@COMEFROM Açıkça geçen anlamına mı geliyorsunuz? Seni doğru anlıyorsam, not alabilirim. Herhangi bir işlevin kendisine açıkça aktarılan veriler üzerinde çalışabileceği göz önüne alındığında, statik bir yöntemin açıkça statik olmayan verilere erişebileceğini ima ettim.
KChaloux

22

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.


2

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.


2

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";
    }
}

Bu teknik olarak statik olmayan verileri kullanan statik bir yöntem olsa da, noktayı özlüyor. Elbette yeni bir örnek oluşturabilir ve ona erişebilirsiniz. Fakat bunun staticNess ile hiçbir ilgisi yok .
Bobson

2
Aslında, bunun konuyu açıklamaya çok iyi bir katkı olduğunu düşünüyorum. Statik yöntemin, statik olmayan verilere erişmeden önce sınıfın bir örneğine ihtiyaç duyduğu, bunun neden olduğu sezgisel bir neden olduğu noktasını vurgulamaktadır.
Ben Hocking

@Bobson Kodu ve yorumları da okumalısınız.
m3th0dman 12:13

@BenHocking "evet" bile ben "örneği değişken her zaman nesne ile ilişkili" olduğu iyi bir nokta söylüyorum olduğunu düşünüyorum
JAVA

2

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.


Katılmıyorum. Statik bir yöntem, örnek verilere erişemiyor çünkü örnek verilere, bir nesnenin örneği üzerinden erişilmesi gerekiyor ve statik yöntem, herhangi bir örnekle (ancak sınıf tanımıyla) ilişkilendirilmiyor.
Phill W.

Amacımı özledin. Eğer bu sınıfın içinden deniyor statik sınıf olmadığı zaman öyle gibi derleyici bir örnek işaretçisi geçebileceği. Sorun, başka bir yerden çağrılırsa ortaya çıkar - bu, özel statik yöntemlerin, örnek verilere erişebildiği anlamına gelir (dahili olarak statik
elektriği yok

Evet, derleyici / olabilir / fakat neden olmasın? Böyle bir işaretçiyi geçmek, esasen onu bir örnek yöntemine indirger. Bunu yapabilen sadece özel yöntemler olduğunu düşündüğünüz şey çok fazla - Yansıma teknolojileri / tüm / yöntemleri erişilebilir kılar - özel veya değil - bunu daha da riskli bir teklif haline getirir. Redmond'daki Dostlarımız diğer yöne gitti; Bir nesne örneğine karşı (sınıfın kendisi değil) statik bir yöntem çağırmaya çalışırsanız, dilleri bir uyarı verir.
Phill W.

1

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.


1

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;
    }

}

Bu soruyu soruyu nasıl cevaplıyor?
tatarcık

1
@gnat Netleştirmek için yorumlar ile güncellendi.
altmış ayağı hafta

1

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.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.