2012-11-09 19 views

Odpowiedz

24

Dzieje się tak, ponieważ kompilator nie byłby w stanie wykryć przeciążenia we wszystkich kontekstach.

Na przykład, jeśli zadzwonisz

String x = method1("aaa"); 

kompilator wie, że szukasz drugiej przeciążenia. Jednakże, jeśli zadzwonisz

method1("aaa"); 

takiego, kompilator nie ma pojęcia, który z dwóch metod Państwo chcieli powołać, bo to jest OK, aby wywołać metodę powracającego String i odrzucić wynik. Aby uniknąć takich niejasności, Java zabrania przeciążania, które różnią się wyłącznie typem zwracanym.

3

nie można przeciążać metody tylko na jego typ zwracany. To po prostu nielegalne. Załóżmy na chwilę, że przeciążanie metod przy użyciu typu zwrotu byłoby legalne i zdefiniowałeś dwie metody: method1. Teraz chcemy nazwać to, co zwraca String object:

String string = method1(sth);

JVM teoretycznie byłby w stanie rozpoznać, jaką metodę inteded zadzwonić, ale co takiego połączenia:

method1(sth);

Jak widać obie metody mogą być wywoływane, a takie operacje są jednoznaczne. JVM nie wie, którą metodę powinien wywołać. Dlatego takie przeciążanie jest zabronione.

+0

+1 za odpowiedź. – Raghunandan

+5

Nie możesz, bo nie możesz? Naprawdę? – m3th0dman

+0

Wyjaśniłem to w edytorze;) Przesłałem krótki post, ponieważ pisanie odpowiedzi na tak proste pytania jest jak wyścig, więc jeśli możesz proszę, odrzuć swój głos. –

0

można wywołać funkcję jako procedurę: method1("arg");, gdzie metoda1 jest drugą metodą na liście (String method1(String arg){}). Kompilator wówczas nie byłby w stanie odróżnić go od pierwszego (void method1(String arg){}).

1

Ponieważ niemożliwe jest rozwiązanie, które z przeciążonych metod powinny być nazywane w takim wypadku:

public static void main(String... args) { 
    method1("aaa"); 
} 
-1

Methode przeciążanie sprawdzana jest na podstawie liczby i rodzaju argumenty nie na podstawie zwrotu type.Thats dlaczego dostajesz błąd.

+0

Pytanie brzmi - dlaczego ten błąd. –

+0

Ponieważ jest to próba zdefiniowania dwóch metod z tym samym sygnaturą. Jest to sprawdzane w tabeli metode i nie jest dozwolone. –

+0

Dlaczego to nie jest dozwolone? –

3

Ponieważ twoje pytanie nie odnosi się do konkretnego języka programowania w tytule (wiem, że robi to w tagu) podzielę się moim ostatnim doświadczeniem z Swift. W Swift Podpis funkcji/metody faktycznie zawiera typ zwrotu. Więc kompilator zgłasza błąd tylko jeśli wywołać tę funkcję/metodę bez wyraźnie określającego typ zwracany, np .:

func some() -> Bool { 
    return true; 
} 

func some() -> Int { 
    return 1; 
} 

let valBool: Bool = some() 
let valInt: Int = some() 

// this doesn't work: Ambiguous use of 'some' 
some() 

Na górę Swift sprawia, że ​​nawet bardziej interesujące. Pozwala na posiadanie 2 funkcji/metod o tych samych parametrach i typach zwracania tylko wtedy, gdy nazwy parametrów są różne, np.:

func some(#foo: Bool) -> Bool { 
    return foo; 
} 

func some(#bar: Bool) -> Bool { 
    return bar; 
} 

some(foo: true) 
some(bar: false) 

Tak więc to daje semantyczne rozróżnienie w metodach podpisu

UPD. Od Swift 2.0 zewnętrzny nazwa parametr został zmieniony i teraz trzeba podać nazwy zewnętrznych i lokalnych dwukrotnie, nawet jeżeli jest to ten sam

func some(foo foo: Bool) -> Bool { 
    return foo; 
} 

func some(bar bar: Bool) -> Bool { 
    return bar; 
} 

some(foo: true) 
some(bar: false) 
+0

+1 dla szerszej perspektywy niż java. Interesujące byłoby usłyszeć swoją opinię na temat tego, czy wymagane wygody przewyższają problemy związane z tym wyborem.Przypuszczam, że dla prostych typów zwracanych, które nie mają większego znaczenia, ale dla obiektów, może to pozwolić na ponowne użycie zmiennych zmiennych wyjściowych ... a następnie nie pozwalając ci łatwo zignorować wartości zwracanej, którą widzę jako cechę, a nie huzel. – Slava

0

Istnieje kilka punktów do rozważenia przy projektowaniu rzeczy jak rozmiar przeciążenia.

Powody pominąć przeciążenia na Zwraca typ:

  1. Uproszczenie ignorując wartości zwracanej przez funkcję (jak ludzie często robią z kodów błędów).
  2. Sprawia, że ​​program jest łatwiejszy do strawienia dla ludzkich czytelników. W szczególności jest to powód, dla którego w Pythonie w ogóle nie występują przeciążenia funkcji. (kwestia gustu)
  3. C Spuścizna. Kiedy język pochodzi z rodziny C-i projektanci nie uważają coś za wielka sprawa jest pozostawiona jak zawsze było ...

powodów, aby dodać przeciążenia na Zwraca typ:

  1. Makijażu Trudno zignorować zwrócone wartości. Może to być wygodne i oszczędza trochę pisania, ale na pewno cię ugryzie.
  2. Ekspresyjność (oczywiście w przeciwieństwie do łatwości trawienia :)). Czy kiedykolwiek chciałeś pisać takie rzeczy, jak int x = json.get("int_value"); float y = json.get("float_value");? W niektórych językach (takich jak C++), które wciąż można osiągnąć za pomocą serwerów proxy i operatorów odlewania, ale przeciążenie na typie powrotu byłoby o wiele łatwiejsze.
  3. Ekspresyjność. Za każdym razem, gdy przekażesz wartość retun jako odniesienie do swojej funkcji tylko po to, aby ponownie użyć jej zasobów, może to być przeciążenie na typie powrotu (z ukrytym parametrem). Rozważ string s; getline(cin, s); vs string s = getline(cin);. I tu właśnie ekspresyjność łączy się z referencyjną przezroczystością, a ostatecznie z łatwością trawienia kodu.

Powróć teraz do pytania "dlaczego?". Ponieważ pytałeś o Javę, odpowiedź jest oczywista dlatego, że James cenił powody, dla których pominięto zwłoki typu powrotu z powodów, dla których zawarł je w języku.

Powiązane problemy