Java:Coś sensownego

Ta część obejmuje techniki manipulacji ciągów znaków i przepływu programu. Przynajmniej twój program będzie działał w mniejszym ukryciu, będzie mógł do ciebie mówić i zacznie robić bardziej skomplikowane operacje! I nie, nie zrobimy gry.

## Obiekty a typy

Jak pewnie już wiesz po przeczytaniu poprzedniego kursu, Java cię nienawidzi. Są tego racjonalne dowody. Jednym z nich są dwa typy zmiennych.

Dokładnie tak. Gdy tworzysz zmienną, możesz zrobić zmienną lub zmienną. Wcześniej zrobiliśmy zmienne i mogliśmy je między sobą zamieniać rodzajami, te zmienne nie są takimi zmiennymi.

O co właściwie chodzi? Cóż, w Javie istnieją *klasy* i *typy prymitywne.* To drugie już poznałeś, są to te zwykłe zmienne, które mogą się wzajemnie zamieniać (np. duża liczba na zwykłą liczbę - long na int). Klasy to są tak naprawdę obiekty. Dlatego każda klasa może zostać stworzona jako zmienna - ale zmienna obiektowa. Typy prymitywne jednak nie są ani klasami, ani obiektami.

Trochę mylące, co? Najtrudniejsze za nami.

Otóż Java potrzebuje klas, aby istnieć. Wszystko, co nie jest tym pierwszym rodzajem zmiennej, jest drugim. Klasa jest nawet potrzebna do uruchomienia zwykłego programu, jak mogłeś zauważyć w ostatnich przykładach (magiczna linijka "public class").

Do czego może służyć obiekt, czyli klasa? Okazuje się, że nie wszystko istnieje po włączeniu programu - takie problemy natury egzystencjalnej. Klasy i elementy **statyczne** istnieją od początku programu - dlatego można ich użyć od samego początku. Zauważ, że metoda *main* z naszego pierwszego programu jest statyczna - dlatego najzwyczajniej w świecie działa.

Dobra, a co zrobić, gdy obiekt nie jest statyczny? Odpowiedź jest prosta - trzeba go stworzyć. Spójrzmy poniżej:

```
String zdanie = new String();

```

Tak tworzy się nowy obiekt typu *String.* Po lewej stronie znaku równości mamy samą deklarację (czyt. "chcę zmienną String"). Po prawej mamy inicjację (czyt. "chcę, aby była obiektem String"). Od momentu wpisania inicjacji, czyli tego po znaku równości, zmienna jest prawdziwym obiektem.

Taki stworzony obiekt ma teraz swoje zmienne i funkcje we wnętrzu, których można używać wyłącznie od momentu stworzenia zmiennej. Np. przed utworzeniem zmiennej zdanie nie możesz wyciąć fragmentu zdania, używając pewnej ciekawej funkcji.

Obiekt może mieć zmienne i funkcje zarówno statyczne, jak i zwykłe. Czyli czasem trzeba tworzyć obiekt, czasem nie.

Pamiętaj - Java cię nienawidzi.

### Po cholerę tak mieszać?

Tak naprawdę w Javie miały pierwotnie istnieć wyłącznie obiekty. Jednak jakiś człowiek zauważył, że Java chodzi u niego zbyt wolno (jakby właśnie o to nie chodziło w Javie) i uznał, że cały kod na obiektach jest zły. Doszło do paru decyzji i wynikiem tego było powstanie typów prymitywnych, które są zapisywane bezpośrednio w pamięci i obiektów, które są zapisywane jako klasy ze swoją zawartością.

Jednak w Javie pamiętano o historii i oprócz tych prymitywów jak int i double pozostawiono oryginalne klasy. Przykładowo istnieją klasy *Integer* i *Double*, które oprócz zastosowania nie mają nic wspólnego z wcześniej wspomnianymi typami.

Uwaga! Typu podstawowego nie inicjuje się jak obiektu. Niemożliwe więc jest wykonanie czegoś takiego:

```
int liczba = new int();

```

Jest to oczywisty błąd. Jak go popełnisz to jesteś pierdoła i nieuważnie czytałeś kurs.

## Stringi

*Gdzie są twoje stringi, ja ich nie widziałem...*
W Javie łańcuchy znaków, czyli zbiory liter nazywamy Stringami. Bynajmniej chodzi tu powiązanie z bielizną, ty parszywy zboczeńcu, nazwa pochodzi od angielskiego określenia liny. String nie jest typem prymitywnym, a więc tworzy się go używając obiektu String. Do wartości zmiennej możemy od razu podstawić jakiekolwiek tekst, ale wyłącznie w cudzysłowie.

```
String smutnaPrawda = "Wszystko co kochasz kiedyś odejdzie.";

```

Stringi można oczywiście łączyć. Robi się to za pomocą plusa.

```
String polaczoneZdanie = "To " + "ma sens.";

```

Java pozwala też na łączenie Stringa i innych zmiennych.

```
int dwa = 2;
String cztery = "2" + 2;
System.out.println(cztery);

```

Niestety, dla zmyłki program wyświetli "22". To dlatego, że zmienna "cztery" ma wartość "22". To idiotyczne utrudnianie życia bierze się od zasady, że od kiedy coś staje się Stringiem (lub dowonym innym obiektem), nie stanie się z powrotem poprzednim typem. Stąd do "2" dopisuje się kolejną dwójkę, ale jako tekst, a nie liczbę.

### Let's go deeper!

String tak naprawdę jest obiektem, ale w swojej zawartości trzyma zbiór typów prymitywnych *char.* Char to typ reprezentujący dokładnie jeden znak, np. jedną literę. Jest typem prymitywnym, a więc przechowuje dane bezpośrednio w pamięci. Dlatego może to robić w jedyny możliwy sposób - jako liczba (a co, myślałeś, że zera i jedynki w komputerze potrafią jakoś inaczej?). A więc w przypadku char przechowuje się liczbę reprezentującą znak.

Znaki zawsze zapisujemy w apostrofach, w przeciwieństwie do Stringów.

```
char a = 'a';

```

Czy powiedziałem, że znaki są przechowywane jako liczby? Nikt chyba nie zabroni nam w takich razie zrobić coś takiego:

```
char znak = 56; // fuck the system

```

Oczywiście to jest jak najbardziej możliwe. Możemy tak wyświetlać identyfikatory (czyli numery) wprowadzonych znaków, czy nawet dodawać znaki jak liczby! Ale nikomu to nie jest potrzebne, dlatego w następnym kursie się tym zajmiemy.

Zaraz, zaraz... Czy do Stringów nie można było dodawać? To dlaczego char na to pozwala?

Jeżeli jeszcze tego nie zauważyłeś String jest obiektem. Nie możesz dodać czegokolwiek do obiektu, ale możesz je łączyć w całość. Stąd wcześniej 2 musiało zostać zamienione na Stringa "2" i dopisane do zmiennej.

## Scanner

Czy kiedykolwiek marzyłeś o tym, aby wpłynąć na program podczas jego działania? Np. wpisać tekst, a on go wyświetli?

Wiem, że nie, ale pewnie jeszcze tego nie potrafisz. Jako Zakonnik Klawiatury jednak musisz umieć. Z pomocą w tym przypadku przyjdzie nam obiekt *Scanner*!

Jeszcze nie zapomniałeś, jak się tworzy obiekty? Świetnie, bo będzie nam to potrzebne. Scanner nie jest statyczny, a więc musimy utworzyć zmienną (i zainicjować ją).

Aby wczytywać dane z klawiatury, w nawiasie będziemy musieli podać "System.in".

```
Scanner scanner = new Scanner(System.in);

```

Stringi wyświetlaliśmy używając System.out.println() - a więc System.out służył do "wypychania" wnętrza programu na zewnątrz, na ekran. Teraz potrzebujemy czegoś całkowicie przeciwnego - dlatego czytamy z System.in, "wciągamy" dane z powrotem do programu.

Scanner po stworzeniu posiada takie przydatane funkcje jak np. *nextLine()*, które wczytuje Stringa. Nazwa dodatkowo wskazuje, że wczyta całą linię.

Jednak zdarza się, że będziemy chcieli pobrać liczbę. Scanner uwzględnia i te przypadki i posiada metody *nextInt()* i *nextDouble()* dla kolejno liczb całkowitych i zmiennoprzecinkowych.

Ten przykładowy program wyświetla to, co wpiszemy, a następnie wprowadzoną liczbę:

```
public class Program {
   public static void main(String args[]) {
     Scanner podajMi = new Scanner(System.in);

     String cokolwiek = podajMi.nextLine();
     System.out.println(cokolwiek);

     int liczba = podajMi.nextInt();
     System.out.println(liczba);
   }
 }

```

Prześledźmy, co ten program robi. Tworzy Scannera "podajMi", niżej tworzy Stringa "cokolwiek" i nadaje jej wartość wprowadzonych danych używając "podajMi". Potem wyświetlamy wartość "cokolwiek". Po wyświetleniu znowu pobieramy wartość, tym razem liczby całkowitej i zapisujemy do zmiennej "liczba". "Liczba" jest na końcu wyświetlana w oddzielnej linijce.

Zauważ, że funkcje zawarte w obiekcie używamy przez kropkę (*podajMi.nextLine(), podajMi.nextInt()*). Analogicznie używaliśmy "System.out.println()", ale nie musieliśmy tworzyć zmiennej, bo to szczególny przypadek (funkcje statyczne, jak napisałem we wstępie).