Statik bir yöntem neden bir yöntem olarak kabul edilir?


135

Bir ders için bazı kod için bir açıklama yazıyorum ve yanlışlıkla kelimeleri kullanarak methodve functionbirbirinin yerine. Geri dönüp ifadeleri düzeltmeye karar verdim, ancak anlayışımda bir delik açtım.

Anladığım kadarıyla, bir altyordam functionbir sınıfın bir örneği üzerinde etki etmezse (etkisi açık girdisi / çıktısıyla sınırlıdır) ve methodbir sınıfın bir örneği üzerinde çalışıyorsa (taşıyabilir onu kirleten yan etkiler ortaya çıkarır).

Bir var burada iyi tartışma konu üzerine. Kabul edilen yanıtın tanımlarına göre, methodbir örnek hiçbir zaman dolaylı olarak iletilmediğinden ve herhangi bir örneğin üyelerine erişimi olmadığından statikin aslında bir işlev olması gerektiğini unutmayın.

Bununla birlikte zihin, statik olmamalıdır methods aslında fonksiyonlar ?

Tanımlarına göre bir sınıfın belirli örnekleri üzerinde hareket etmezler; sadece ilişki nedeniyle sınıfa "bağlıdırlar". Statik altprogramlara "yöntemler" olarak atıfta bulunan birkaç iyi görünümlü site gördüm ( Oracle , Fredosaurus , ProgrammingSimplified ), bu yüzden ya terminolojiye bakmıyorlar ya da bir şey eksikim (tahminim sonuncusu) .

Doğru ifadeyi kullandığımdan emin olmak istiyorum.
Birisi bunu temizleyebilir mi?


2
Her zaman Java php ve yönteminde işlev olduğunu düşündüm. Temelde farklı isimlerle aynı şey
JK

19
Teorik bilgisayar bilimi ile bir dilin onu nasıl uyguladığı arasında bir fark vardır. JLS hiçbir ayrım yapmaz ve ona bir yöntem der.
Jeroen Vannevel


2
Bu "fonksiyonu" ve orada Python, içinde "yöntemi" tanımlarına bakmak ilgisini çekebilecek olan temelde bir işlev sembolü tabloyla kodu ve bir çağırma kuralı bir yığın yöntemi ne ise şöyledir: Bir fark bir işlevi sınıfa koyduğunuzda elde edersiniz. Python'u bilen insanlar için bile fark oldukça incedir.
David Z

2
Teori öğrenirken, fonksiyonun bir değer döndürdüğünü ve prosedürün geri dönmediğini öğrendim. Sonra java çağrı fonksiyonları ve prosedürleri yöntemleri öğrendim. Şimdi fonksiyonel programmjng deniyorum ve bir işlev idempotent. Terimler bağlamdaki anlamı değiştirir.
emory

Yanıtlar:


123

8.4.3.2'deki bu alıntı yardımcı olabilir:

Bildirilen yönteme sınıf yöntemistatic denir .

Bildirilmeyen staticbir yönteme örnek yöntemi [...] denir .

  • Sınıf yöntemleri: bir sınıfla ilişkilendirilir.
  • Örnek yöntemleri: bir örnekle ilişkilendirilir.

Java sadece "nesne yönelimli düşünmenizi" istiyor. Ayrıca, statik yöntemlerin durum içerebilen bir çevre kapsamına erişimi vardır. Bir bakıma, sınıf bir nesnenin kendisi gibidir.


Bununla birlikte, "işlev" teknik olarak Java'da bir yürütme birimi olarak doğru olsa da, tüm Java işlevleri bir sınıfın veya arabirimin (lambdas hariç, belki farkında olmadığım başka şeyler).
Shotgun Ninja

1
Lambdas aslında @FunctionalInterfaceek açıklama ve başlık altında 1 yöntem ile anonim iç sınıflardır . Bir lambda sadece sözdizimsel şekerdir ve bu bakımdan yeni bir şey yoktur.
Adam Arold

1
Arodam Lambdas, anonim bir iç sınıftan biraz daha meraklıdır. Örneğin, yakalamayan lambdalar belirli bir ifadenin birden çok değerlendirmesinde bir örneği paylaşabilir. (Ama haklısın sonuçta statik ve örnek yöntemlere
derleniyorlar

@Radiodef Belki bunu ifade etmenin daha iyi bir yolu, "Tüm lambda ifadeleri, lambda ifadesini içeren dosyadan başka bir dosyada herhangi bir değişiklik yapılmadan eşdeğer lambda olmayan ifadelerle değiştirilebilir" veya bunun gibi bir şey olabilir.
user253751

4
Utandım. Scala'dan geliyorum ve hala sınıfın kendisinin nesne benzeri olduğu gerçeğini kaçırmayı başardım. Teşekkür ederim.
Carcigenicate

80

Basit cevap, Java her şeyi bir "yöntem" olarak adlandırmaya karar verdiğinde, teorik bilgisayar bilimlerinde bir işlev ve bir yöntem arasındaki farkı umursamadıklarıdır.


3
Doğru. Java 7 dahil olmak üzere ve Dil Spesifikasyonu'nda
Erwin Bolwidt

4
Bu cevabın basitliğini sevdiğim kadarıyla, Radiodef'in cevabının daha çok yol aldığını düşünüyorum çünkü sınıfın kendisinin bir nesne olarak davrandığı kilit noktadan bahsediyor. Yine de teşekkürler.
Carcigenicate

2
İlginç bir şekilde, bu, önceki dillerin işlevler ve altyordamlar arasında ayrım yapmama kararlarına paraleldir.
Random832

4
Bu cevabın bu kadar çok oyu almasından rahatsız oldum. İlk olarak, bu cevap sınıf yöntemlerinin yokmuş gibi davranmaktadır. İkincisi, bu Java'da tanıtılan bir kavram değildir. Smalltalk'ta sınıf yöntemleri zaten vardı, örneğin, Java bir şey haline gelmeden onlarca yıldır vardı.
Malcolm

1
@ Malcolm Seninle aynı fikirdeyim. Diğer cevapları düşündükten sonra, bu yanlış görünüyor. Gerçekten umursamadıkları, ancak ne olursa olsun doğru isimlendirmedikleri sürece Java yaratıcısının ilgisizliği değildir.
Carcigenicate

26

Statik yöntemler tam olarak işlev değildir, fark incedir, ancak önemlidir.

Sadece verilen giriş parametreleri kullanılarak bir statik bir yöntem olup , esas bir fonksiyonu.

Ancak statik yöntemler, statik değişkenlere ve diğer statik işlevlere erişebilir (statik değişkenler de kullanarak), bu nedenle statik yöntemlerin , temelde tanımı vatansız olan bir işlevden temel olarak farklı bir durumu olabilir . (EK: Programcılar genellikle tanım olarak "işlev" kullanmakla o kadar katı olmasa da, bilgisayar bilimindeki katı bir işlev yalnızca girdi parametrelerine erişebilir). Bu nedenle, statik alanlara erişme örneğini tanımlamak, statik yöntemlerin her zaman işlevler olduğunu söylemek geçerli değildir.

"Statik yöntemin" kullanımını haklı kılan bir diğer fark, C'de tanımlayabileceğiniz, her yerde erişilebilen global fonksiyonları ve global değişkenleri türetmesidir. Statik yöntemler içeren sınıfa erişemiyorsanız, yöntemlere de erişilemez. Dolayısıyla "statik yöntemler", küresel işlevlerin aksine tasarımla kapsamlarıyla sınırlıdır.


2
Bu cevabı beğendim ama bazı şeyleri daha iyi anlamak istiyorum. Bu, işlev ve yöntem yerine "saf" ve "yan etkili" bir işlev değil midir? Yoksa bir yöntemin yan etkilerden dolayı mı böyle olduğu? Ben sadece burada beyin fırtınası yapıyorum.
Nadir Sampaoli

2
Bu cevap doğru. Bununla birlikte, birçok (en çok?) Dilde işlevlerin küresel değişkenlere erişebileceği iddia edilebilir, bu nedenle genellikle kesinlikle vatansız değildir (aynı girdi, aynı çıktı). Java statik yöntemlerinde, sınıf değişkenlerine erişmek, "global" (yani bir işlev / yöntem için yerel değil) değişkenlere erişmek için eşdeğer kabul edilebilir - sınıf örneği bir tür ad alanıdır.
leonbloy

1
@leonbloy Saf Haskell gibi fonksiyonel programlama dilleri tamamen vatansızdır; küresel değişken olarak adlandırılabilecek hiçbir şey yoktur.
Thorsten S.

17

Java'da, kullanıcı tanımlı bir sınıf aslında java.lang.Class alt sınıfının bir örneğidir.

Bu anlamda, statik yöntemler vardır kavramsal sınıfının bir örneğine bağlı: onlar java.lang.Class alt sınıfının bir örneğine eklenir.

Bunu akılda tutarak, "sınıf yöntemi" terimi (Java'nın statik yöntemleri için alternatif bir ad) anlamlı olmaya başlar. Ve "sınıf yöntemi" terimi birçok yerde bulunabilir: Amaç C, Smalltalk ve JLS - bunlardan sadece birkaçı.


Bu alt sınıfın iki örneği olabilir mi?
Random832

Elbette, bir sınıfı farklı sınıf yükleyicilere yükleyebilirsiniz (ClassCastExceptions öğesinin "CustomClass'ı CustomClass'a yayınlayamıyor" mesajıyla almanın nedeni).
dunni

2
@ Random832 - bir çeşit. Her örneğin kendi ayrı sınıf yükleyicisi olduğu sürece, aynı JVM'de aynı Sınıf alt sınıfının iki (veya daha fazla) örneğine sahip olabilirsiniz. Her Classloader için aynı Class alt sınıfını bir kereden fazla başlatamazsınız. Biraz kafa karıştırıcı oluyor ve klasik OO konseptlerine benzetmeler bu noktada biraz zayıflamaya başlıyor.
Mike Clark

@MikeClark bunu yaparsam, gerçekten aynı mı? Sınıfın kendisi de sınıfın farklı bir örneği olsa bile Sınıf alt sınıfı aynı sınıf mı olacak? Sınıf doldurucular benim için oldukça kafa karıştırıcı. Bir sınıf yükleyicinin bir sınıf örneğinin aynı sınıftaki başka bir sınıf yükleyicisinin örneğinden statik bir yöntem çağırabilir, buna bir başvuru göndererek? Farklı yöntemleri varsa ne olur?
Random832

1
@ Random832 "Sıralansın mı?" Tamamen OO teorisi açısından bakıldığında, bir sınıfın iki örneği gerçekten aynı mıdır? En azından aynı sınıfın aynı iki örneğinin farklı adresleri olacaktır. Aksi halde, iki şeyden nasıl yararlanabiliriz? Bir şeyle tamamen aynı olan tek şey , şeyin kendisidir.
Mike Clark

11

Bilgisayar bilimlerinde işlev statik bir yöntemle açıkça eşleşir. Ancak bir sınıfın "method" değeri "member" (alan üyesi, yöntem üyesi) gibi biraz geneldir. Gibi ifadeler var

Veri üyeleri ve yöntem üyelerinin iki ayrı ad alanı vardır: .x ve .x () bir arada bulunabilir.

Bunun nedeni, Ludwig Wittgenstein'ın dediği gibi, Dilin farklı bağlamlara sahip bir araçtır. "Yöntem" yukarıdaki alıntıda bir "üye" kategorize etmek için hoş bir takma addır.


9

Düşünceleriniz doğru ve mantıklı. Java topluluğunda yerleşik bir terminoloji değil. Terminolojinin neden yaşandığını anlamaya yardımcı olabilecek bazı içselleri açıklayayım.

Java, sınıf tabanlı nesne yönelimli bir dildir. Bir yöntem her zaman bir sınıf veya örneğin üyesidir (Bu, diğer programlama dilleri için de geçerli olan genel bir deyimdir). Sınıf ve örneğin her iki nesne olduğunu düşünüyoruz.

Örnek yöntemi (dinamik)

Bu yöntemi doğrudan bir sınıftan çağıramazsınız, bir örnek oluşturmanız gerekir. Her örnek bu yönteme başvurur. Tam olarak aynı yöntem imzasıyla (alt sınıflandırma sırasında) bir yöntem tanımının üzerine yazabilirsiniz, yani başvuru farklı bir yönteme işaret eder (aynı imzayı taşır, ancak farklı bir yöntem gövdesine sahip olabilir). Yöntem dinamiktir.

Sınıf yöntemi (statik)

Bu yöntemi yalnızca sınıftan doğrudan çağırabilirsiniz, yani bu sınıfın bir örneğini oluşturmanız gerekmez. Tüm programda bu yöntemin yalnızca tek bir global tanımı vardır. Tüm program için geçerli tek bir tanım olduğundan, yöntem statik olarak bildirildiğinde tam olarak aynı yöntem imzasının üzerine yazamazsınız. Yöntemin sınıf nesnesinin kendisinin üyesi olduğunu, örneklerin bu yönteme aynı benzersiz (ve düzeltme) başvurusuna sahip olduğunu unutmayın.


7

İşte kullanarak terminoloji başka almak olduğunu Scala bir anımsatıcı olarak:
In Scala sahip objectbir örtülü olarak tanımlanan sınıfın tekil örnekleri olan s,1 .

Tanımınıza göre, sınıfın tek bir örneğinde çalıştıkları için object yöntemlere ait bu alt yordamları çağırabiliriz .
Ek olarak, nesne A sınıfını da tanımlayacak ve A nesnesindeki tüm yöntemleri A sınıfında statik yöntemler olarak oluşturacaktır (Java ile arabirim için) [2] .

Bu nedenle, Java sınıfı A'nın statik yöntemlerinin, tanımınıza göre A sınıfı (statik) yöntemler olarak adlandırılmayı hak eden Scala singleton örneğiyle aynı üyelere eriştiğini söyleyebiliriz .


Harika bir karşılaştırma. Scala'yı biliyorum, bu yüzden objectreferansınız çok mantıklı. Teşekkür ederim.
Carcigenicate

2

Tabii ki, temel fark - yöntem sadece yöntem parametrelerini değil, statik alanları da kullanabilir. Ama ek bir tane var - polimorfizm! Değerlendirme sonuçları A.doTheSameStaticMethod () ve ClassB.doTheSameStaticMehod (), sınıfa bağlı olacaktır. Bu durumda işlev iktidarsızdır.


1

Her sınıfın onu temsil eden bir nesnesi vardır ve bu sınıfın alt sınıfının bir örneğidir. Class sınıfın . Statik yöntemler, bu nesneler üzerinde gerçekten bir Class alt sınıfının örnekleri olan örnek yöntemlerdir. Statik alanlar şeklinde duruma erişimleri vardır, bu nedenle sadece (vatansız) işlevlerle sınırlı değildirler. Onlar yöntemdir.

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.