Programowanie obiektowe w Javie

Transkrypt

Programowanie obiektowe w Javie
Programowanie obiektowe w Javie
Michał Kasiński, Przemysław Białkowski
Wydział Matematyki i Informatyki UŁ
12 kwietnia 2013
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
1 / 32
Krótka historia Javy
Język Java (początkowo Oak) powstał w 1991 na potrzeby
wielofunkcyjnego urządzenia *7. Urządzenie miało służyć jako
bezprzewodowy, dotykowy kontroler urządzeń domowych. Tajny projekt
”Green” (początkowo ”Stealth”) zainicjowany był przez firmę Sun
Microsystems a bezpośrednio pracowali nad nim m.in. James Gosling, Mike
Sheridan i Patrick Naughton.
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
2 / 32
Historia wersji
JDK 1.0 (23 Stycznia 1996) ”Oak” Pierwsze stabilne wydanie JDK to
1.0.2, nazywane zwyczajowo Java 1.
JDK 1.1 (19 Lutego 1997) zmiany w AWT, klasy wewnętrzne,
JavaBeans, JDBC, RMI, refleksje
J2SE 1.2 (8 Grudnia 1998) ”Playground”, integracja Swing, JVM z
kompilatorem JIT, Java plug-in(aplety), Java IDL (implementacja
CORBY), Collection framework(kontenery)
J2SE 1.3 (8 Maja 2000) ”Kestrel”, HotSpot JVM, modyfikacja RMI
dla kompatybilności z CORBA, JavaSound, Java Naming and
Directory Interface(JNDI), Java Platform Debugger
Architecture(JPDA)
J2SE 1.4 (6 Lutego 2002) ”Merlin” wydany poprzez Java Community
Process, wyrażenia regularne, łańcuchy wyjątków, parser XMLa
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
3 / 32
Historia wersji c.d.
J2SE 5.0 (30 Września 2004) ”Tiger” programowanie uogólnione,
adnotacje, autoboxing, typy wyliczeniowe, Varargs, for-each
Java SE 6 (11 Grudnia 2006) ”Mustang” ulepszenia wydajności m.in.
odśmiecacza
27 Stycznia 2010, Oracle kupiło Sun Microsystems.
sierpień 2010, Oracle pozywa Google o naruszenie praw autorskich i
patentów.
10 Grudnia 2010, Apache Software Foundation opuszcza JCP.
Java SE 7 (28 Lipca 2011) ”Dolphin” drobne zmiany w języku
(projekt Coin), String w switchu, try-with-resources
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
4 / 32
Przebieg procesu budowania
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
5 / 32
Podstawowe polecenia - javac i java
Kod źródłowy Javy umieszczamy w plikach o rozszerzeniu ”.java”,
pamiętając o tym, że:
jeden plik .java odpowiada jednej klasie publicznej
przynajmniej w jednej klasie publicznej musi znaleźć się metoda
”main” - taką klasę nazywamy klasą główną.
Kompilacja odbywa się za pomocą kompilatora javac:
Przykład
$ cd Hello
$ javac HelloWorld.java
Program uruchamiamy za pomocą polecenia java. Spowoduje to
uruchomienie maszyny wirtualnej, załadowanie odpowiednich klas i
wywołanie metody main.
Przykład
$ java HelloWorld
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
6 / 32
Podstawowe polecenia - javadoc i javap
Ciekawym narzędziem do tworzenia dokumentacji jest javadoc. Z
odpowiednio przygotowanych komentarzy wygeneruje dokumentacje w
HTMLu. Dodanie flagi -author spowoduje dodanie informacji o autorze.
Przykład
$ javadoc HelloJavadoc.java -d docs -author
Kolejnym ciekawym narzędziem jest javap. Jest do disassembler javy.
Dodanie flagi -c pozwala na podgląd kodu bajtowego.
Przykład
$ javap -c HelloWorld.class
$ javap -c HelloJavadoc.class
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
7 / 32
Podstawowe polecenia - jar
Narzędziem do strukturalizacji i kompresji plików .class jest jar. Tworzy
ono archiwum o rozszerzeniu .jar. Jest to archiwum ZIP zawierające
dodatkowo automatycznie generowany plik META-INF/MANIFEST.MF.
Do pliku manifest można dodawać pewne informacje, np. klasę główną (z
metodą main). Jar z wyszczególnioną klasą główną stanowi aplikację.
Przykład
$ jar cfm HelloWorld.jar Manifest.txt HelloWorld.class
HelloJavadoc.class
$ java -jar HelloWorld.jar
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
8 / 32
Klasa
W javie klasy deklarujemy za pomocą słowa kluczowego class. Nazwy klas
piszemy wielką literą.
Przykłady klas
class Rower{}
public class Osoba{}
Modyfikatory dostępu
W javie wyróżniamy cztery modyfikatory dostępu: public, protected,
private i package-private(niejawny). W stosunku do klas możemy użyć
dwóch z nich: publicznego i pakietowego (patrz przykłady wyżej). Klasa
publiczna będzie widoczna z dowolnego miejsca w kodzie programu. Klasa
o dostępie pakietowym, będzie widoczna w obrębie swojego pakietu (i w
klasach znajdujących się w pakietach nadrzędnych).
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
9 / 32
Pakiet
Pakiet jest jednostką podobną do katalogu w systemie plików, służącą do
grupowania klas ze względu na pewne zgodne elementy lub/i logiczne
związki np. podobną funkcjonalność, przynależność. Przy nadawaniu nazw
pakietów stosuje się zwykle pewną ustaloną konwencję. Nadrzędny pakiet
nazywamy odwrotnie do swojej domeny. W przypadku naszego wydziału
będzie to pl.lodz.uni.math, następnie możemy dodać pakiet sygnalizujacy
o osobie, organizacji np.:
pl.lodz.uni.math.kowalcr
pl.lodz.uni.math.dziekanat.halina
i ostatecznie pakiety związane z programem czy jego elementami
pl.lodz.uni.math.kasa.grafy.reprezentacje
pl.lodz.uni.math.kasa.grafy.algorytmy
Pakiety określamy w kodzie za pomocą słowa kluczowego package.
Przykład
/Pakiet/src/pl/lodz/uni/math/kasa/przyklad/Przyklad.java
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
10 / 32
Składowe klasy
Do odzwierciedlenia stanu i zachowania obiektu danej klasy potrzebne są
pewne zmienne(i stałe) oraz funkcje. W javie zmienne i stałe w danej
klasie nazywa się polami a funkcje i procedury - metodami. Modyfikatory
dostępu dotyczą także składowych klas. Publiczne składowe są widoczne
poza pakietem, chronione są widoczne w klasie oraz w klasach
pochodnych od danej klasy, pakietowe w obrębie pakietu, a prywatne w
obrębie klasy. Zgodnie z paradygmatem programowania obiektowego
powinniśmy dbać o enkapsulacje kodu i przyjmować w miare możliwości
ograniczony - prywatny dostęp.
Przykład
/Dostęp/Dostep.java
/Dostęp/PrivateObjectMain.java
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
11 / 32
Mechanizm refleksji
Java dopuszcza zarządzanie kodem w trakcie działania programu za
pomocą mechanizmu refleksji. Refleksje są stosowanie między innymi przy
twórzeniu różnych narzędzi dla języka - stosowanie ich przy standardowym
programowaniu jest niezalecane (a często niepotrzebne), gdyż utrudnia
sprawdzanie poprawności i zaburza czytelność. W przykładzie możemy
zobaczyć w jaki sposób pozyskać dostęp do prywatnych pól klasy.
Przykład
/Dostęp/PrivateObjectMain.java
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
12 / 32
Konstruktory
Pewnym szczególnym rodzajem metody jest konstruktor, który służy to
tworzenia instancji obiektu danej klasy. Konstruktor przyjmuje taką samą
nazwę jak klasa. Klasa może mieć kilka zdefiniowanych konstruktorów.
Jeżeli nie utworzymy żadnego konstruktora, java zrobi to za nas i utworzy
publiczny konstruktor bezargumentowy. Jeżeli utworzymy konstruktor, to
kompilator nie pozwoli na utworzenie obiektu w inny sposób niż za
pomocą tego konstruktora.
Przykład
/Konstruktory/Pies.java
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
13 / 32
Niszczenie obiektów
W javie w odróżnieniu od C++ nie ma destruktorów. Projektanci języka
uznali sposób zarządzania pamięcią w języku C++ za niewygodny i
zastosowali inne rozwiązanie - Garbage Collector. Możliwe jest jawne
wywołanie Garbage Collectora poprzez metodę System.gc() aczkolwiek
jest to jedynie sugestia dla maszyny wirtualnej, tj. nie ma gwarancji, że
Garbage Collector zostanie wywołany wraz z System.gc().
Uwaga!
W javie nie ma destruktorów.
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
14 / 32
Słowo kluczowe final
Słowo kluczowe final w języku java daje różne rezultaty w zależności od
kontekstu.
Klasa finalna oznacza, że inne klasy nie mogą po niej dziedziczyć.
Metoda finalna oznacza, że musi ona być zaimplementowana tylko i
wyłącznie w klasie w której jest zadeklarowana.
Pole finalne oznacza, że można mu przypisać wartość tylko raz i nie
można jej zmienić. Należy mieć na uwadze, że w typach
referencyjnych chodzi o referencję do obiektu a nie o sam obiekt,
który może zmienić swój stan.
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
15 / 32
Dziedziczenie
W javie dziedziczenie realizujemy za pomocą słowa kluczowego extends.
Rozważmy dwie klasy: Dziad i StaryDziad. Zwracając uwagę na klasę
StaryDziad ze zwykłej ludzkiej ciekawości nasuwa się pytanie o wiek. W
przypadku obu klas możemy mówić o cesze wspólnej jaką jest imię. W tym
wypadku typem bardziej ogólnym jest Dziad. Mówimy, że Dziad jest klasą
macierzystą a StaryDziad klasą pochodną. W języku Java fakt ten
zapisujemy jako class StaryDziad extends Dziad Przyjrzyjmy się
ponadto chronionej metodzie składowej ustawWiek(int wiek);
Domyślnie wszystkie klasy dziedziczą(niejawnie) po klasie bazowej Object.
Dziedziczenie po Object - obie formy równoważne
public class Osoba{}
public class Osoba extends Object{}
Przykład
/Dziedziczenie/Protected/StaryDziad.java
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
16 / 32
Klasy abstrakcyjne
Klasy abstrakcyjne w javie zasadniczo nie różnią się od klas abstrakcyjnych
w C++. Jedyna różnica wynika z innego nazywania pewnych pojęć. W
C++ klasą abstrakcyjną nazywaliśmy klasę, która posiadała przynajmniej
jedną metodę w pełni wirtualną. W Javie wszystkie metody są domyślnie
wirtualne (dają się przeciążyć). Metoda w pełni wirtualna w javie to
inaczej metoda abstrakcyjna. Wobec klasy i metody abstrakcyjnej w javie
używamy słowa kluczowego abstract. Inna różnica wynika z braku
wielodziedziczenia w Javie. W Javie można dziedziczyć tylko po jednej
klasie bazowej.
Przykład
/Dziedziczenie/Klasa Abstrakcyjna/Music4.java
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
17 / 32
Interfejsy
Interfejs w javie jest bytem nieco przypominającym klasę abstrakcyjną.
Interfejsy tworzymy w javie za pomocą słowa kluczowego interface po
którym następuję nazwa interfejsu pisana wielką literą. Interfejs można
opisać obrazowo jako w pełni abstrakcyjną klasę - taką która nie posiada
implementacji. O klasie która ”dziedziczy po” interfejsie, mówimy, że go
implementuje, albo realizuje. Interfejsy są domyślnie publiczne.
Najważniejszą funkcjonalnością jaką dostarczają interfejsy, jest możliwość
implementowania wielu, przez jedną klasę.
Przykład
/Dziedziczenie/Interfejs/Games.java
/Dziedziczenie/Interfejs/InterfaceCollisions.java
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
18 / 32
Typy prymitywne
Typ
boolean
char
byte
short
int
long
float
double
Zawiera
true lub false
znak Unicode (unsigned)
wartość całkowita (signed)
wartość całkowita (signed)
wartość całkowita (signed)
wartość całkowita (signed)
IEEE 754 z. p. pojedynczej precyzji
IEEE 754 z. p. podwójnej precyzji
M.K. P.B. (WMiI)
Java
Domyślnie
false
/u0000
0
0
0
0
0.0f
0.0
Rozmiar
1 bit
2 bajty
1 bajt
2 bajty
4 bajty
8 bajtów
4 bajty
8 bajtów
12 kwietnia 2013
19 / 32
Typy referencyjne
Typy referencyjne to takie typy do których możemy się odnosić za pomocą
referencji. Generalnie możemy podzielić je na:
klasy: Osoba
interfejsy: Comparable
zmienne typu: T //programowanie generyczne
tablice: String [] args
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
20 / 32
Autoboxing/unboxing
Od Javy SE 5.0 możemy cieszyć się automatyczną konwersją między
typami prymitywnymi i ich referencyjnymi odpowiednikami. Zapewnia to
większą czytelność kodu, jednak wiąże się to ze stratami na wydajności
(odpowiedniki typów prymitywnych są niezmienne(immutable)). Trwają
dyskusję na temat zupełnego przejścia na typy referencyjne.
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
21 / 32
Instrukcje warunkowe - if
if
if (wyrażenie logiczne)
instrukcja
if-else
if (wyrażenie logiczne)
instrukcja
else
instrukcja2
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
22 / 32
Instrukcje warunkowe - switch
switch
switch (selektor-całkowity){
case wartość-całkowita1 : instrukcja1; break;
case wartość-całkowita2 : instrukcja2; break;
..
.
default: instrukcja;
}
Uwaga
Od Javy w wersji 7 dopuszczalny jest selektor typu String w instrukcji
switch.
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
23 / 32
Iteracje
while
while (wyrażenie logiczne)
instrukcja
do-while
do
instrukcja
while (wyrażenie logiczne);
for
for(inicjalizacja; wyrażenie-logiczne; krok)
instrukcja
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
24 / 32
Pętla for-each
Od Javy SE 5.0 dopuszcza się nową odmiane składni pętli for,
przeznaczoną do przeglądania elementów kontenerów i tablic. Składnię
foreach można stosować na dowolnym obiekcie implementującym interfejs
Iterable.
Przykład
Składnia/Foreach.java
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
25 / 32
Wyjątki
Wyjątki są integralnym elementem programowania w Javie. Ich stosowanie
znacznie poprawia jakość programu. Idea wyjątku polega na dopuszczeniu
sytuacji wyjątkowej i świadomym przekazaniu problemu do szerszego
kontekstu, lub do naprawy.
Przykład
/Wyjątki/FinallyWorks.java
/Wyjątki/Rethrowing.java
/Wyjątki/RethrowingNew.java
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
26 / 32
Try-with resources
Od Javy SE w wersji 7 mamy możliwość sprawniejszego zamykania
pewnych zasobów za pomocą konstrukcji try-with-resources.
try-with-resources
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
W tym przypadku zasobem do zamknięcia jest BufferedReader. Z racji, że
BufferedReader implementuje interfejs AutoClosable, zostanie on
automatycznie zamknięty niezależnie od efektu metody readLine() (która
może wyrzucić wyjątek).
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
27 / 32
Obsługa strumieni
Złożoność obsługi wejścia i wyjścia w javie jest związana z dość dużą
ilością klas. Różnorodność początkowo działa na programistów javy
odstraszająco (jak na ironię system w javie został zaprojektowany tak, aby
zapobiec eksplozji klas). Skupmy się na kilku rozwiązaniach czytania
pewnych źródeł i pisaniu do pliku.
Przykłady
/IO/Czytanie/ReadString.java
/IO/Czytanie/ScannerReadFile.java
/IO/Czytanie/URLReader.java
/IO/Pisanie/WriteToFileExample.java
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
28 / 32
Programowanie generyczne
Programowanie uogólnione (generyczne) w javie jest realizacją
polimorfizmu statycznego. Jest to podejście odpowiadające szablonom w
języku c++. Sens programowania generycznego sprowadza się do pisania
klas bez znajomości typów danych na których te klasy będą operowały.
Przykłady
/Generyczne/Member.java
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
29 / 32
Wydajność
Dlaczego java jest wolniejsza niż c/c++?
Historia, mity, uprzedzenia i eskalacja agresji.
Czym jest warmup?
O co chodzi z tym JIT? ”-XX:+PrintCompilation” i ”-Xint”
Czy Garbage Collector wpływa na wydajność?
Odpowiedzi
Java, jak każdy język interpretowany jest wolniejsza od języków kompilowanych
takich jak C++. Jednak ze względu na usprawnienia takie jak kompilator JIT jej
wydajność w niewielu przypadkach nie ustępuje C++. Każdy programista Javy
powinien zdawać sobie sprawę z jej zalet oraz wad względem innych języków,
zwłaszcza, że wokół Javy narosło wiele mitów i głoszonych jest wiele
nieprawdziwych informacji. W internecie można znaleźć materiały odpowiadające
na powyższe pytania. Polecam również uruchomienie aplikacji w katalogu
/Wydajność z podanymi w punkcie czwartym flagami oraz przeanalizowanie
wyników. W razie jakichkolwiek wątpliwości czy pytań pozostaje w kontakcie:
[email protected]
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
30 / 32
Zapowiedzi
Project Coin(m.in. proste przeciążanie operatorów)
Java SE 8: wyrażenia lambda, adnotacje na typach javy, integracja z
JavaFX
Java 9: Lepsze wsparcie dla dużych stert, elastyczna JVM
spekulacje na temat porzucenia typów prymitywnych
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
31 / 32
Dziękujemy za uwagę :-)
Pytania?
M.K. P.B. (WMiI)
Java
12 kwietnia 2013
32 / 32