Linuksowo.pl - Linux forum
Transkrypt
Linuksowo.pl - Linux forum
Subject: java i enum Posted by b00rt00s on Wed, 22 Sep 2010 22:15:55 GMT View Forum Message <> Reply to Message Mam taki fragment kodu: enum Scales { OFFSET {double result(double argument, double offset) { return argument+offset; }}, MULTIPLY {double result(double argument, double multiplier) { return argument*multiplier; }}, POW {double result(double argument, double exponent) { return Math.pow(argument, exponent); }}; abstract double result(double x, double y); } I ten kod kompiluje się dobrze. Jeśli jednak postanowię zmodyfikować kod w ten sposób: enum Scales { OFFSET {double result(double argument, double offset) { return argument+offset; }}, MULTIPLY {double result(double argument, double multiplier) { return argument*multiplier; }}, POW {double result(double argument, double exponent) { return Math.pow(argument, exponent); }}, LOG {double result(double argument) { return Math.log10(argument); }}; //dodana linia kodu abstract double result(double x, double y); abstract double result(double x); //dodana linia kodu } to w takiej sytuacji kod się nie kompiluje. Komunikat błędu jest następujący: Exception in thread "main" java.lang.ExceptionInInitializerError at wykres.Scaling.main(Scaling.java:58) Caused by: java.lang.RuntimeException: Uncompilable source code - <anonymous wykres.Scales$1> is not abstract and does not override abstract method result(double) in wykres.Scales at wykres.Scales.<clinit>(Scaling.java:6) ... 1 more Java Result: 1 Problem jak widać dotyczy przesłaniania metod abstrakcyjnych. Jeśli usunąć modyfikatory abstract (i dodać byle jakie ciała metod) to kod kompiluje się właściwie. Sęk w tym, że mnie zależy na tych modyfikatorach i na braku bezsensownych ciał metod. Czy da się to w jakiś sensowny sposób rozwiązać? Subject: Odp: java i enum Page 1 of 5 ---- Generated from Linuksowe by FUDforum 2.8.1 Linuksowo.pl - Linux forum - Polskie Forum Posted by hwast on Thu, 30 Sep 2010 21:40:16 GMT View Forum Message <> Reply to Message Wybierz sobie rozwiązanie:enum Scales { OFFSET { double result(double argument, double offset) { return argument+offset; } }, MULTIPLY { double result(double argument, double multiplier) { return argument*multiplier; } }, POW { double result(double argument, double exponent) { return Math.pow(argument, exponent); } }, LOG { double result(double argument, double dummy) { return Math.log10(argument); } }; abstract double result(double x, double y); } enum Scales { OFFSET { double result(double[] argument) { return argument[0]+argument[1]; } }, MULTIPLY { double result(double[] argument) { return argument[0]*argument[1]; } }, POW { double result(double[] argument) { return Math.pow(argument[0], argument[1]); } }, Page 2 of 5 ---- Generated from Linuksowe by FUDforum 2.8.1 Linuksowo.pl - Linux forum - Polskie Forum LOG { double result(double[] argument) { return Math.log10(argument[0]); } }; abstract double result(double[] arg); } enum Scales { OFFSET { double result(double argument, double offset) { return argument+offset; } double result(double argument) { return argument+argument; } }, MULTIPLY { double result(double argument, double multiplier) { return argument*multiplier; } double result(double argument) { return argument*argument; } }, POW { double result(double argument, double exponent) { return Math.pow(argument, exponent); } double result(double argument) { return Math.pow(argument, argument); } }, LOG { double result(double argument, double dummy) { return Math.log10(argument); } double result(double argument) { return Math.log10(argument); } }; Page 3 of 5 ---- Generated from Linuksowe by FUDforum 2.8.1 Linuksowo.pl - Linux forum - Polskie Forum abstract double result(double x, double y); abstract double result(double x); } Mam nadzieję, że choć trochę pomogłem ci zrozumieć kwestię przeładowywania metod specjalizowanych dla typów wyliczeniowych. Zacznę od ostatniego przykładu - zachowuje się to trochę tak, jakby każde wyliczenie było klasą wewnętrzną, implementującą interfejs klasy zewnętrznej. Nie zaglądałem do żadnych kodów źródłowych bibliotek javy, więc nie wiem czy właśnie tym jest enum, czy to tylko drobne podobieństwo. Nie siedzę w Javie także tak długo by paniętać wersje < 1.5, gdzie (jeśli dobrze się orintuję) typy wyliczeniowe nie były dostępne w java.lang.* Wskazuje na to także możliwość gładkiego wywołania System.out.println(Scales.LOG.LOG.LOG.result(10)); W drugiej propozycji użyłem tablic do przechowywania argumentów. Jeśli twój typ wyliczeniowy nie został nigdzie zaimplementowany, poza twoim własnym kodem i żadne osoby trzecie go nie używają - to chyba najlepsze rozwiązanie. Tablica jest naszym odpowiednikiem stosu na którym lądują argumenty funkcji i do którego nie mamy niestety dostępu :( Pamiętaj aby dobrze to opisać w komentarzach JavaDoc! Pierwszy przykład jest najbardziej toporny i chłopski - działa, jest niewiele kodu, ale narzuca użycie 2 argumentu-wydmuszki.. Subject: Odp: java i enum Posted by b00rt00s on Fri, 01 Oct 2010 16:05:52 GMT View Forum Message <> Reply to Message hwast napisał(a) dnia czw, 30 wrzesień 2010 11:40 Zacznę od ostatniego przykładu - zachowuje się to trochę tak, jakby każde wyliczenie było klasą wewnętrzną, implementującą interfejs klasy zewnętrznej. Jest dokładnie tak jak mówisz. Dotarłem do tego sam nieco wcześniej. Problem rozwiązałem tak, że dodałem do logarytmu argument bazy ;). W ten sposób zawsze trzeba podać dwa argumenty. Dzięki jednak za pomysł z tablicą. Jednak bardziej elegancko byłoby zrobić interfejs tak: abstract double result(double... arg); W takiej sytuacji metoda result jest metodą ze zmienną ilością parametrów, a zmienna arg jest tablicą typu double. Oczywiście wywołanie metody wygląda np.: tak: Page 4 of 5 ---- Generated from Linuksowe by FUDforum 2.8.1 Linuksowo.pl - Linux forum - Polskie Forum System.out.println(result(1.5, 1.2)); System.out.println(result(1.5)); System.out.println(result(1.5, 1.2, 6)); Page 5 of 5 ---- Generated from Linuksowe by FUDforum 2.8.1 Linuksowo.pl - Linux forum - Polskie Forum