Prawie zawsze program w jakiś sposób dokonuje interakcji z użytkownikiem — prosi o wprowadzenie jakichś danych lub wyświetla jakieś informacje. W tej lekcji dowiemy się jak obsługiwać najprostszą interakcję — za pomocą linii komend.
Linia komend (zwana też wierszem poleceń) to tekstowy tryb obsługi komputera. Zanim w komputerach pojawił się tryb graficzny, pozwalający obsługiwać go za pomocą m.in. myszki, podstawowym sposobem obsługi komputera był tryb tekstowy. Do tej pory jest on wykorzystywany w niektórych aplikacjach, także my z niego skorzystamy na początku.
Lekcja
Pierwszy program
Żeby móc zacząć pisać kod i sprawdzać jak będzie działał, musimy powiedzieć Javie że to, co piszemy może bezpośrednio uruchomić. Szczegółowo omówimy to w kolejnych lekcjach, ale na tą chwilę to, co musisz wiedzieć, to to, że wystarczy dodać do naszej klasy metodę o sygnaturze public static void main(String[] args), a w jej ciele zaimplementować to, co chcemy zrobić. Ponieważ omówienie i szczegółowy opis pojawi się na blogu później, zainteresowanych odsyłam do krótkiego opisu z wyjaśnieniami w języku angielskim. A u nas na tę chwilę wersja instant — fragment kodu:
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
Aby przypomnieć sobie, jak uruchomić nasz program, możesz zajrzeć na stronę o narzędziach i środowisku.
Pojawia się tutaj pierwszy nieznany nam element, przejdźmy zatem do wyjaśnienia, co on robi.
Wypisywanie danych dla użytkownika
Podstawowym sposobem na wypisywanie czegoś w konsoli są dwie metody: System.out.print(..) oraz System.out.println(..) . Jedyną różnicą jest to, że druga z nich wypisuje też znak końca linii — tzn. kursor w konsoli przechodzi do następnego wiersza zaraz po wypisanym tekście.
Aby wyświetlić użytkownikowi informację “Podaj imię” wystarczy zapisać w naszym programie polecenie:
System.out.print("Podaj imię: ");
Spowoduje to wyświetlenie powyższego pytania w oknie konsoli, a znak zachęty pojawi się na lewo od naszego pytania.
Chcąc wyświetlić dodatkowo wartość pewnej zmiennej, możemy po prostu ją ‘dodać’ (dokonać konkatenacji). Należy jednak uważać, ponieważ nie każdy obiekt możemy w ten sposób dodać lub to, co zostanie wyświetlone będzie niezrozumiałe dla użytkownika.
Integer zmienna = 1;
System.out.print("Wartość zmiennej: " + zmienna);
Tutaj uwaga natury technicznej: używanie polskich znaków w konsoli jest problematyczne, ponieważ dochodzi tutaj kwestia kodowania znaków, które jest różne w różnych systemach (dla zainteresowanych — w systemach Windows używamy cp1250). Oczywiście Java daje narzędzia pozwalające ten problem rozwiązać, ale tematyka ta jest poza obszarem tego kursu, a w dalszych etapach wczytywanie danych będziemy realizowali w bardziej kontrolowany sposób. Dlatego kwestię polskich znaków w oknie konsoli w ramach tego kursu zignorujemy.
Jeśli chodzi o wyświetlenie w oknie konsoli, to jest podstawowy sposób i wszystkie inne korzystają z niego ostatecznie. Oczywiście istnieje wiele możliwości formatowania wyjścia, wyświetlania liczb z określoną precyzją, dat w określonym formacie, ale prawda jest taka, że niewiele aplikacji posiada interfejs tekstowy, z którego korzystają użytkownicy. Nam będzie to potrzebne do nauki kilku kolejnych elementów po czym zajmiemy się bardziej współczesnymi sposobami na interakcję z użytkownikiem. Z tego powodu, poprzestaniemy na tej podstawowej wiedzy. Zainteresowanych odsyłam np. do dokumentacji klasy Formatter, która jest jednym z prostszych a jednocześnie potężnych narzędzi służących do formatowania wyjścia w języku Java.
Wczytywanie danych od użytkownika
Jeśli chodzi o wczytywanie danych, mamy zdecydowanie więcej możliwości i opcji. Podstawowy sposób to odczyt bajt po bajcie (czyli znak po znaku) i następnie sklejanie z tego informacji, które chcemy wczytać od użytkownika. Jest to rozwiązanie bardzo elastyczne, ale sprawiające równie dużo kłopotów, szczególnie początkującym programistom. Skorzystamy więc z innej klasy, którą oferuje nam Java — Scanner. Klasa ta jest bardzo uniwersalna, pozwala nam na obsługę konsoli, plików, strumieni (czyli np. danych pobieranych z internetu czy streamingu video), wykorzystamy tylko jej podstawowe funkcjonalności. Ale zachęcam do eksperymentów, nie ugryzie (w przeciwieństwie do Tesli na diecie) :)
Przede wszystkim zdefiniujmy w naszej klasie pole o nazwie sc i typie Scanner (a umiemy już to robić):
static Scanner sc = new Scanner(System.in);
To co robi ta linijka, to deklaruje pole o nazwie sc (nazwa oczywiście jest dowolna, ważne żeby używać jej poprawnie w odpowiednich miejscach w kodzie) i przypisuje do niego nowy obiekt typu Scanner, który jako źródło danych wykorzystuje System.in (tzw. standardowe wejście — stąd możemy uzyskać to, co użytkownik wpisze w konsoli).
Następnie dodajemy do tej klasy metodę (to też umiemy już robić), której będziemy używać za każdym razem, kiedy będziemy potrzebowali wczytać dane od użytkownika. Metoda ta wygląda następująco:
public static String getUserInput() {
return sc.nextLine();
}
Metoda ta zwraca następną linijkę z wejścia (czyli tego co wpisał użytkownik) za każdym razem kiedy zostanie wywołana. Wykorzystuje do tego metodę nextLine z klasy Scanner (jeśli chcemy wcześniej sprawdzić, czy użytkownik wpisał cokolwiek wcześniej i zabezpieczyć się przed sytuacją ‘zawieszenia’ aplikacji, można użyć metody hasNextLine() z tejże klasy — zachęcam do wyszukania przykładu lub poeksperymentowania samodzielnie).
Uwaga: metoda Scanner.nextLine ‘blokuje się’ dopóki użytkownik nie wpisze czegoś i nie zatwierdzi klawiszem ‘Enter’. Oznacza to, że aplikacja będzie czekała aż użytkownik nie wpisze czegoś i nie zatwierdzi tego enterem. Dopóki to się nie stanie, żadna dalsza akcja nie zostanie wykonana.
Jeśli dodaliśmy opisane wyżej elementy, w dowolnym miejscu naszej klasy możemy napisać np:
System.out.print("Podaj imię: ");
String imieWczytaneOdUzytkownika = getUserInput();
To tyle :) I tak, to naprawdę jest tak proste, tutaj nie ma haczyków ;)
Dwa słowa o tym, czym jest ‘static’
Jak pewnie zauważyłaś, wszystkie elementy, które tworzyliśmy w kodzie były statyczne — tzn poprzedzaliśmy je słówkiem ‘static’. Dzięki temu, możliwe było ich użycie w metodzie main (czyli głównej metodzie programu), bez konieczności tworzenia nowego obiektu aplikacji. To, że metoda lub pole jest statyczne, oznacza, że jest one ‘własnością’ klasy, a nie konkretnej instancji obiektu. Dzięki temu nie ma potrzeby tworzenia nowego obiektu tylko po to, aby wywołać jakąś metodę. Konsekwencją jest oczywiście to, że takie metody nie mają dostępu do pól konkretnych obiektów, a jedynie do innych pól i metod statycznych. W naszym przypadku nie stanowi to jednak problemu i jest drobnym uproszczeniem, które stosujemy w kodzie.
Zadanie
Utwórz klasę interfejs. Klasa ta powinna być aplikacją (tzn. żeby można było ją uruchomić) i powinna pytać o nastepujące elementy:
- imię kota
- opiekun
Oraz zapisywać je w utworzonym na początku działania programu obiekcie kotka (jesli nie pamiętasz jak to zrobić, zajrzyj do lekcji #01, gdzie mówimy o setterach).
Rozwiązanie
Rozwiązania do lekcji są dostępne w serwisie GitHub — użyj przycisków po prawej aby pobrać lub przejrzeć kod do tej lekcji. Jeśli masz wątpliwości, jak posługiwać się Git’em, instrukcje i linki znajdziesz w naszym wpisie na temat Git’a.
Jeśli uważasz powyższą lekcję za przydatną, mamy małą prośbę: polub nasz fanpage. Dzięki temu będziesz zawsze na bieżąco z nowymi treściami na blogu ( i oczywiście, z nowymi częściami kursu Javy). Dzięki!