Soru Aşırı yükleme, derleme zamanı polimorfizmidir. Gerçekten mi?


Aşırı ve aşırı yükleme arasındaki sözdizimsel farkı biliyorum. Üstelik, aşırıya kaçmanın çalışma zamanı polimorfizmi olduğunu ve aşırı yüklemenin derleme zamanı polimorfizmi olduğunu da biliyorum. Ama sorum şu: "Aşırı yükleme gerçekten derleme zamanı polimorfizmi midir? Metot gerçekten derleme zamanında çözmeyi gerektiriyor mu?" Benim amacımı açıklığa kavuşturmak için, bir örnek sınıfı düşünelim.

public class Greeter {
    public void greetMe() {
        System.out.println("Hello");
    }

    public void greetMe(String name) {
        System.out.println("Hello " + name);
    }

    public void wishLuck() {
        System.out.println("Good Luck");
    }
}

Tüm yöntemler beri greetMe(), greetMe(String name), wishLuck() herkese açıktır, hepsi de aşırı yüklenebilir (aşırı yüklenmiş olanlar dahil), değil mi? Örneğin,

public class FancyGreeter extends Greeter {
    public void greetMe() {
        System.out.println("***********");
        System.out.println("*  Hello  *");
        System.out.println("***********");
    }
}

Şimdi, aşağıdaki kod parçasını düşünün:

Greeter greeter = GreeterFactory.getRandomGreeter();
greeter.greetMe();

getRandomGreeter() yöntem rastgele döndürür Greeter nesne. Bir nesneyi iade edebilir Greeterveya alt sınıflarından herhangi biri gibi FancyGreeter veya GraphicalGreeter ya da başka biri. getRandomGreeter() kullanarak nesneleri oluşturacak new veya sınıf dosyasını dinamik olarak yükleyin ve yansımayı (yansıma ile mümkün olduğunu düşünüyorum) veya mümkün olan başka bir yolu kullanarak nesne oluşturun. Tüm bu yöntemler Greeter Alt sınıflarda olabilir veya olmayabilir. Bu yüzden derleyicinin, belirli bir yöntemin (aşırı yüklenmiş veya yüklenmemiş) geçersiz olup olmadığını bilmenin bir yolu yoktur. Sağ? Ayrıca wikipedia diyor Sanal fonksiyonlar:

Java'da, tüm statik olmayan yöntemler varsayılan olarak "sanal işlevler" dir.       Yalnızca geçersiz anahtar kelimeyle işaretlenmiş, geçersiz kılınamayan yöntemler,       devralınmayan özel yöntemlerle birlikte sanal değildir.

Sanal işlevler dinamik yöntem gönderimini kullanarak çalışma zamanında çözüldüğünden ve tüm özel olmayan, son olmayan yöntemlerin sanal olduğundan (aşırı yüklenip yüklenmediğinden), çalışma zamanında çözülmesi gerekir. Sağ?

Daha sonra, aşırı yükleme hala derleme zamanında nasıl çözülebilir? Ya da yanlış anladığım bir şey var mı, yoksa özlüyorum mu?


21
2017-12-02 11:50


Menşei




Cevaplar:


Aşırı yüklenen yöntemler, eğer sorduğunuz buysa, yine de geçersiz kılınabilir.

Aşırı yüklenen yöntemler, aynı adı paylaşmalarına rağmen farklı aileler gibidir. Derleyici, imza verilen bir aileyi statik olarak seçer ve daha sonra çalışma zamanında sınıf hiyerarşisindeki en özel yönteme gönderilir.

Yani, yöntem gönderme iki adımda gerçekleştirilir:

  • Birincisi, mevcut statik bilgi ile derleme zamanında yapılır, derleyici bir call Yöntemin uygulandığı nesnenin bildirilen tipindeki aşırı yüklenmiş yöntemler listesindeki geçerli yöntem parametrelerinizle eşleşen imza için.
  • İkinci adım, çağrılacak yöntem imzası (önceki adım, hatırlayın?) Göz önünde bulundurulduğunda, çalışma zamanında gerçekleştirilir, JVM, gerçek alıcının tipindeki en aşırı beton versiyonuna gönderir.

Metod argümanları türleri hiç değişmezse, aşırı yükleme, derleme zamanında karıştırılan yöntem adlarına sahip olmakla eşdeğerdir; çünkü bunlar etkili bir şekilde farklı yöntemlerdir, JVM, alıcının tipine bağlı olarak bunları asla değişmez bir şekilde göndermeyecektir.


9
2017-12-02 11:54



Aşırı yüklü yöntemlerin geçersiz olabileceğini biliyorum. Ancak, derleme zamanı polimorfizmi aşırı yüklenen yöntemlere nasıl uygulanır? Onlar da geçersiz kılınabilir ve bu nedenle çalışma zamanında çözülmelidir. Sağ? - Jomoos
Bu aile meselesini biraz daha açıklayabilir misiniz? - Jomoos
Jomoos: derleyici, derleme listesinden seçim yapmak için aşırı yüklenme yöntemlerinden hangisini çözebilir, çünkü argüman listesi geçersiz kılarak değiştirilemez. Çalışma zamanında, JVM, yalnızca, bu "versiyon" (derleme zamanında aşırı yüklenmiş versiyonlardan seçilmiş) olarak adlandırılması gereken hangi nesne ile çözülür. Hükümdarın şartlarını affedersem, derin bir CS arka planım yok. - prasopes


Her 'Greeter' sınıfının 3 sanal yöntemi vardır: void greetMe(), void greetMe(String), ve void wishLuck().

Aradığın zaman greeter.greetMe() Derleyici, üç sanal yöntemin hangisinin yöntem imzasından çağrılacağını öğrenebilir - örn. void greetMe() bir argüman kabul etmediği için. Hangi özel uygulama void greetMe() yöntem denir türüne bağlıdır greeter Örneğin ve çalışma zamanında çözülür.

Örneğinizde, derleyicinin, hangi yöntem yöntemini kullanacağını anlaması önemsizdir, çünkü yöntem imzaları tamamen farklıdır. 'Derleme zamanı polimorfizmi' kavramını göstermek için biraz daha iyi bir örnek aşağıdaki gibi olabilir:

class Greeter {
    public void greetMe(Object obj) {
        System.out.println("Hello Object!");
    }

    public void greetMe(String str) {
        System.out.println("Hello String!");
    }
}

Bu karşılama sınıfını kullanarak aşağıdaki sonuçları verecektir:

Object obj = new Object();
String str = "blah";
Object strAsObj = str;

greeter.greetMe(obj); // prints "Hello Object!"
greeter.greetMe(str); // prints "Hello String!"
greeter.greetMe(strAsObj); // prints "Hello Object!"

Derleyici, derleme zamanı türünü kullanarak en özgün eşleme yöntemini seçer, bu nedenle ikinci örnek çalışır ve void greetMe(String) yöntem.

Son çağrı en ilginç olanıdır: Çalışma zamanı strAsObj türü olsa bile String, bir Object bu yüzden derleyici böyle görür. Yani, derleyici bu çağrı için bulabileceğiniz en yakın eşleşme void greetMe(Object) yöntem.


11
2017-12-02 12:37





Polimorfizm nedir?

Aks. bana göre: Bir varlık birden fazla biçimde temsil edilebiliyorsa, bu varlığın polimorfizm sergilediği söylenir.

Şimdi, bu tanımı Java yapılarına uygulayalım:

1) Operatörün aşırı yüklenmesi, zaman polimorfizmidir.

Örneğin, + operatör iki dizeyi birleştirmek için iki sayı VEYA eklemek için kullanılabilir. kesinlikle derleme zamanı polimorfizmini söyleyen bir polimorfizm örneğidir.

2) Metodu aşırı yükleme, zaman polimorfizmidir.

Örneğin, aynı ada sahip bir yöntem birden fazla implemente sahip olabilir. aynı zamanda bir derleme zamanı polimorfizmi.

It's compile-time because before execution of program compiler decides the flow of program i.e which form will be used during run-time.

3) Yöntemin geçersiz kılınması, çalışma zamanı polimorfizmidir.

Örneğin, aynı imzaya sahip bir yöntem birden fazla uygulama içerebilir. Bu bir çalışma zamanı polimorfizmi.

4) Türetilmiş sınıf yerine temel sınıf kullanımı, zaman polimorfizmidir.

Örneğin, interface Referans, uygulayıcının herhangi birine işaret edebilir.

It's run-time because the flow of program can't be known before execution i.e. only during run-time it can be decided that which form will be used.

Umarım biraz temizler.


7
2017-12-02 12:26





Bu bağlamda aşırı yükleme, işlev türünün, dinamik dağıtımın aksine derleme zamanında statik olarak belirlendiği anlamına gelir.

Sahnelerin arkasında gerçekten olan şey, "A" ve "B" türlerine sahip "foo" adlı bir yöntem için iki yöntemin oluşturulmasıdır ("foo_A" ve "foo_B"). Onlardan hangisinin çağrılacağı derleme zamanında belirlenir (foo((A) object) veya foo((B) object) sonuçlanmak foo_A çağrılıyor veya foo_B). Yani bu bir şekilde olduğu Gerçek zamanlı yöntem (yani, sınıf hiyerarşisinde hangi uygulamanın uygulanacağı) çalışma zamanında belirlenmiş olsa da, derleme zamanı polimorfizmi.


2
2017-12-02 12:04