Java'da farklı dönüş türleriyle aşırı yüklenme?


105

Sadece dönüş türünü değiştirerek bir işlevi aşırı yüklemek neden mümkün değil? Bu, Java'nın gelecekteki bir sürümünde değişecek mi?

Bu arada, sadece referans için, bu C ++ 'da mümkün mü?



KNU, ​​diğer cevap, soruyu genel olarak, dile özgü olmayan terimlerle sorması bakımından farklılık gösterir. Ayrıca ilginç olan, diğer sorunun kabul edilen cevabının, Java JVM'nin dahili bileşenlerin manipülasyonuyla yapılmasına izin verdiğini belirterek daha da ileri gitmesidir.
J Woodchuck

Yanıtlar:


157

Bunu Java ile yapamazsınız ve C ++ ile yapamazsınız. Mantık, tek başına dönüş değerinin derleyicinin hangi işlevi çağıracağını bulması için yeterli olmamasıdır:

public int foo() {...}
public float foo() {..}

...
foo(); // which one?

3
Her zaman int i = foo () veya float f = foo () gibi bir şey yaparsak hangisinin olduğunu bileceğini düşünmüşümdür, ancak ifade sadece işlev ise derleyicinin bilemeyeceği bir işlevdir. Anlıyorum. Teşekkürler.
nunos

7
@nunos float olsa bile f = foo () derleyici bunu çözemezdi çünkü hem int hem de float için geçerli girdi olurdu. Float f = 7'yi karşılaştırın; (7 bir float mı yoksa int mi?)
NomeN

5
@NomeN Ancak ifadeniz derleyici için func (int i) ve func (float i) 'nin ayırt edilemez olacağını öne sürüyor - ve hepimiz bunun doğru olmadığını biliyoruz. Gerçek neden Oded tarafından verilmiştir (sonraki cevaba bakınız) - bu yöntemin imzası ile ilgilidir. Ve btw. 7 kesinlikle tamsayı, 7.0 veya 7f yüzer ;-)
Ta Sas

7
7.0 değil float, öyle double.
fredoverflow

3
foo();Bir dönüş türünün belirsiz olacağı gerçeği, bir aşırı yükleme olarak buna izin vermemek için bir neden değildir. Belirsizliğe neden olabilecek argümanlar vardır (örneğin foo(null);), ancak bu aşırı yüklemeyi doğal olarak geçersiz kılmaz.
shmosel

48

Bunun nedeni, Java'daki aşırı yüklemelere yalnızca farklı imzalara sahip yöntemler için izin verilmesidir .

Dönüş türü yöntem imzasının bir parçası değildir, bu nedenle aşırı yükleri ayırt etmek için kullanılamaz.

Java eğitimlerinden Yöntemleri Tanımlama bölümüne bakın .


4
Ama iade türü neden imzanın bir
andho

51
oh "çünkü"! Anlıyorum.
andho

3
Dönüş türü, yöntem imzasının bir parçasıdır. Sadece sınıf demontajına bakın.
konmik

2
Bu gerçekten @konmik değil - yöntem aşırı yükleme kurallarına göre değil. Dene. Aynı yöntem adı, aynı sırada aynı parametre türleri, farklı dönüş türleri. Derlenmeyecek.
Oded

3
Evet, çünkü dönüş tipi imzanın bir parçası değil . İmza - yöntemin adı + parametresinin türleri ve sırası. Cevabımda verdiğim bağlantıyı okuyun: "Yukarıda açıklanan yöntemin imzası: calculateAnswer(double, int, double, double)". Dönüş türünün dahil edilmediğine bakın, @konmik.
Oded

22

Java 5.0'dan önce, bir yöntemi geçersiz kıldığınızda, hem parametreler hem de dönüş türü tam olarak eşleşmelidir. Java 5.0'da, kovaryant dönüş türü adı verilen yeni bir özellik sunar. Aynı imzaya sahip bir yöntemi geçersiz kılabilirsiniz, ancak döndürülen nesnenin bir alt sınıfını döndürür. Başka bir deyişle, bir alt sınıftaki bir yöntem, türü, üst sınıfta aynı imzaya sahip yöntem tarafından döndürülen türün bir alt sınıfı olan bir nesneyi döndürebilir.


3
Bunu ilk gördüğümde şaşırmıştım. Bunun neden mümkün olduğunu açıkladığınız için teşekkürler!
Dylan Knowles

2
aşırı yükleme ve geçersiz kılma farklıdır. Aşırı yükleme (zorunlu olarak) kalıtımı içermez
senseiwu

3
Bu cevap, Java'daki bir acemi için yanıltıcı gelebilir, çünkü aşırı yükleme ile hiç alakalı değil , geçersiz kılıyor - tamamen başka bir şey.
azizbekian

4

Overloaded argümanın da farklı olduğu göz önüne alındığında, java'daki yöntemlerin farklı dönüş türleri olabilir.

Örnek koda bakın.

public class B {

    public String greet() {
        return "Hello";
    }

    //This will work
    public StringBuilder greet(String name) {
        return new StringBuilder("Hello " + name);
    }

    //This will not work
    //Error: Duplicate method greet() in type B
    public StringBuilder greet() {
        return new StringBuilder("Hello Tarzan");
    }

}

temelde dönüş türü dikkate alınmaz, sadece argümanlar üzücü ama doğru
Alexander Mills

1

Derleyici yöntemleri farklılaştırırken dönüş türünü dikkate almaz, bu nedenle farklı bir dönüş türüne sahip olsalar bile aynı imzaya sahip iki yöntemi bildiremezsiniz.


1

Bir yöntemi aşırı yüklerken dönüş türü önemli değildir. Sadece belirsizlik olmadığından emin olmalıyız!

Java'nın hangi yöntemi çağıracağını bilmesinin tek yolu, argüman listesinin türlerini farklılaştırmaktır. Derleyici aynı ada ve aynı argüman türlerine sahip iki yönteme izin verirse, hangisini çağırması gerektiğini belirlemenin bir yolu olmazdı.


0

Derleyici yöntemleri farklılaştırırken dönüş türünü dikkate almaz, bu nedenle farklı bir dönüş türüne sahip olsalar bile aynı imzaya sahip iki yöntemi bildiremezsiniz.

İşlev yürütmenin farkındaysanız, bir işlevi çağırdığımızda tanım kısmının çalıştırıldığını ve sonunda return ifadesini istediğimizi fark edeceksiniz, bu nedenle return işlevin tüm tanımından sonra gelir diyebiliriz, bu yüzden iki veya aynı isimde ve aynı tipte ve no. işlev adı ve parametreler aynı olduğundan derleyicinin hangisinin çağrılacağını nasıl bileceği, argümanların sayısıdır. Çağırma sırasında öncelikle tüm odak argümanlar ve fonksiyon adı üzerinde olacak ve sonunda fonksiyon tanımının tamamlanmasından sonra return ifadesi ile ilgileneceğiz.

Derleme Süresi Hatası, Çalışma Süresi Hatasından daha iyidir. Bu nedenle, aynı parametrelere sahip aynı yöntemi bildirirseniz, java derleyici derleyici zamanı hatası oluşturur.


Bunun kabul edilen cevaptan farkı nedir? (Ayrıca nedeni yani nasıl uygun çalıştırılabilir kod oluşturmak gerekiyordu, derleyici çağrısına hangi yöntemi bilemiyorum çünkü bir derleme zamanı hatası olduğunu)
UnholySheep

-2

hayır, bu şekilde gerçekten mümkün değil, yalnızca hiçbir argüman veya argümanların veri türü ile aşırı yükleyebilirsiniz

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.