Dlaczego typ zwrotu nie jest zawarty w podpisie?Dlaczego typ powrotu nie jest zawarty w metodzie podpisu?
Jako przykład -
public void method1(String arg){...}
public String method1(String arg){...}
Spowoduje to błąd
Dlaczego typ zwrotu nie jest zawarty w podpisie?Dlaczego typ powrotu nie jest zawarty w metodzie podpisu?
Jako przykład -
public void method1(String arg){...}
public String method1(String arg){...}
Spowoduje to błąd
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.
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.
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){}
).
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");
}
Methode przeciążanie sprawdzana jest na podstawie liczby i rodzaju argumenty nie na podstawie zwrotu type.Thats dlaczego dostajesz błąd.
Pytanie brzmi - dlaczego ten błąd. –
Ponieważ jest to próba zdefiniowania dwóch metod z tym samym sygnaturą. Jest to sprawdzane w tabeli metode i nie jest dozwolone. –
Dlaczego to nie jest dozwolone? –
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)
+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
Istnieje kilka punktów do rozważenia przy projektowaniu rzeczy jak rozmiar przeciążenia.
Powody pominąć przeciążenia na Zwraca typ:
powodów, aby dodać przeciążenia na Zwraca typ:
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.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.
+1 za odpowiedź. – Raghunandan
Nie możesz, bo nie możesz? Naprawdę? – m3th0dman
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. –