Przygotował: Jacek Sroka 1 Programowanie obiektowe Wykład 4 Pakiety, tablice, przeciążanie metod, kaspułkowanie, inicjalizacja
Przygotował: Jacek Sroka 2 Przypomnienie Kompilator nie generuje kodu maszynowego, ale kod pośredni (bajtkod) Bajtkod wykonuje maszyna wirtualna Javy (Java Virtual Machine JVM) Obecnie również inne języki działają na JVM, np. Scala, Python, Groovy, Ruby, Ada, PHP,... JMV + standard class libraries = JRE JRE to Java Runtime Environment Standardowe biblioteki implementują Java API (Application Programming Interface) Java SE 6 J2SE 1.4.2 i 5.0 SE, ME, EE
Przygotował: Jacek Sroka 3 Klasy Wersja minimalistyczna class Pusta{ Klasa publiczna tylko w pliku o tej samej nazwie Atrybuty class Osoba{ String imię = "Jan"; String nazwisko; Metody class Osoba{ String imię; String nazwisko; String imię(){ return imię; String nazwisko(){ return nazwisko; void nicnierobi() {
Przygotował: Jacek Sroka 4 Typy 8+1 typów podstawowych Obiekty wskazywane przez referencję Dla typów podstawowych są klasy opakowujące Wartości typów podstawowych przechowywane są na stosie, obiekty na stercie Tablice są obiektami
Przygotował: Jacek Sroka 5 Typy podstawowe
Przygotował: Jacek Sroka 6 Wartości domyślne
Przygotował: Jacek Sroka 7 Zasięg deklaracji lokalnych Pracownik prac1 = new Pracownik("Jacek", 10000f); \\tylko prac1 { Pracownik prac2 = new Pracownik("Placek", 8000f); \\prac1 i prac2 \\zmiennych lokalnych nie wolno przesłaniać \\źle: Pracownik prac1 = new Pracownik("Jacek", 10000d); \\tylko prac1
Przygotował: Jacek Sroka 8 Zagadka public class ScopeTest { int x; void test1() { x = x + 2; int x = 1; x = x++; System.out.println(x); void test2(int x) { System.out.println(x); System.out.println(this.x); System.out.println(this.x); public static void main (String[] args) { ScopeTest st = new ScopeTest(); st.test1(); st.test2(1);
Przygotował: Jacek Sroka 9 Pakiety Pomiędzy deklaracją pakietu i deklaracjami klas i interfejsów możemy wskazać jakich klas i interfejsów chcemy używać bez kwalifikowania ich nazw nazwą pakietu: import pak1.pak2.klasa; import pak1.interfejs; import pak1.*; //nie obejmuje podpakietów //java.lang.* jest importowane domyślnie JVM ładuje potrzebne klasy w chwili pierwszego odwołania, a odnajduje je dzięki wartości CLASSPATH (zmienna środowiska lub parametr wywołania) Jeżeli CLASSPATH=/java:. to poszukiwany będzie plik /java/pak1/pak2/klasa.class jeżeli taki nie istniej to./pak1/pak2/klasa.class W CLASSPATH można też wskazać archiwum (jar lub zip) Nie znalezienie importowanej klasy/interfejsu powoduje błąd podczas kompilacji
Przygotował: Jacek Sroka 10 Pakiety przykład package mój.pierwszy.pakiet; import java.util.date; /* wielkość * liter ma * znaczenie */ public class MojaPierwszaKlasa { // a ten komentarz jest tylko do końca linii public static void main(string[] args) { System.out.println("Witaj Świecie!"); javac./mój/pierwszy/pakiet/mojapierwszaklasa.java java mój.pierwszy.pakiet.mojapierwszaklasa
Przygotował: Jacek Sroka 11 Pakiety c.d. Jeżeli pakiety pak1 i pak2 zawierają klasę A to: import pak1.a; import pak2.a; spowoduje błąd podczas kompilacji import pak1.*; import pak2.a; będzie poprawne i używana będzie A z pak2, chyba że A jest również definiowana w aktualnym pakiecie import pak1.*; import pak2.*; będzie poprawne, o ile nigdzie nie próbujemy odwoływać się do A i nie definiujemy tej klasy w aktualnym pakiecie
Przygotował: Jacek Sroka 12 Niektóre standardowe pakiety java.lang (Object, String, Integer,..., System, Math, Throwable, Thread) java.io (File, Reader, Writer, InputStream, OutputStream) java.net (Socket, ServerSocket, URL) java.util (Collection, List, Set, Map, Iterator) javax.swing...
Przygotował: Jacek Sroka 13 Tablice Tablice są obiektami wobec czego są przechowywane na stercie Referencję do tablicy deklarujemy podając typ przechowywanego elementu oraz dodając parę nawiasów kwadratowych po dowolnej stronie identyfikatora: int[] tab; int []tab; int tab[]; int tab []; (który sposób jest najbardziej czytelny?) int[] tab1, tab2; //dwie tablice int tab1[], tab2; //tablica i liczba Tablice mogą być wielowymiarowe: String[][] tabliczka[]; Podczas deklaracji referencji do tablicy nigdy nie podajemy jej rozmiaru! Rozmiar podajemy dopiero tworząc nowy obiekt: int[] tab = new int[5]; String[][] tabliczka = new String[3][5];
Przygotował: Jacek Sroka 14 Tablice c.d. Tablice wielowymiarowe są tak naprawdę tablicami tablic: String[][] tabliczka = new String[2][]; tabliczka[0] = new String[3]; tabliczka[1] = new String[5]; Literałów tablic wolno używać jedynie w miejscu deklaracji: int[] tab = {1, 2, 3,; //ostatni, jest opcjonalny String s = "ela"; String[] t = {"ala", "ola", s, new String("ula"); String[][] tabliczka = {t, {"ala"; W pozostałej części kodu można używać tablic anonimowych: int[] tab; tab = new int[] {1, 2, 3,; //nadal nie podajemy rozmiaru mojafunkcja(new int[] {1, 2, 3,);
Przygotował: Jacek Sroka 15 Tablice c.d. Tablice indeksujemy zaczynając od zera: tab[0] == 1; t[3].equals("ula"); tabliczka[1][4] == null; //jest automatyczna inicjalizacja //"][" nie można zastąpić "," (tabliczka[1,4]) Próba odwołania się poza zakres dostępnych indeksów spowoduje wystąpienie wyjątku ArrayIndexOutOfBoundsException java.util.arrays
Przygotował: Jacek Sroka 16 Przeciążanie metod Metody odróżniamy na podstawie nazwy i listy parametrów Nazwy jakie nadamy parametrom nie mają znaczenia, liczą się jedynie ich typy public void mojametoda(string jakaśnazwa) public void mojametoda(string innanazwa) Czasami metody wykonujemy jedynie dla ich efektów ubocznych, a zwracana wartość nas nie interesuje (więc nie służy do odróżniania metod przeciążonych) space.write(entry, transaction, lease); dodaj(4, 5); //4+5; //nie skompiluje się
Przygotował: Jacek Sroka 17 Przeciążanie i promocja wartości class PrzeciazanieMetod { void f(char x) {System.out.println("char"); void f(byte x) {System.out.println("byte"); void f(short x) {System.out.println("short"); void f(int x) {System.out.println("int"); void f(long x) {System.out.println("long"); void f(float x) {System.out.println("float"); void f(double x) {System.out.println("double"); //void f(object o) {System.out.println("Object"); //void f(string s) {System.out.println("String"); Jak będą promowane wartości? char jest promowany do int (nie do short) Dla obiektów wybierany jest typ bardziej szczegółowy
Przygotował: Jacek Sroka 18 Przeciążanie metod c.d. class PrzeciazanieMetod { void f(short b, int i) {System.out.println("short, int"); void f(int b, short i) {System.out.println("int, short"); //pm.f(1, 1); //żadna metoda nie pasuje //pm.f((short) 1, (short) 1); //pasują obie pm.f(1, (short) 1); //int, short pm.f((char) 1, (byte) 1); //int, short
Przygotował: Jacek Sroka 19 Konstruktor Nazwa taka sama jak nazwa klasy (można przeciążać) Brak typu zwrotnego (nie ma sensu) Zadbajmy, żeby atrybuty osoby nie mogły mieć wartości null class Osoba{ String imię; String nazwisko; Osoba(String imię, String nazwisko){ this.imię = imię; //niedozwolone dla metod static this.nazwisko = nazwisko; String imię(){ return imię; String nazwisko(){ return nazwisko; Domyślny konstruktor bezparametrowy Pierwszą operacją może być wywołanie innego konstr. ale bez cykli this(...);
Przygotował: Jacek Sroka 20 Tworzenie obiektów Każdy obiekt jest inicjalizowany przez wykonanie jakiegoś konstruktora Operator new //Po dodaniu konstr. z param. powoduje błąd kompilacji Osoba o = new Osoba(); //Poprawne Osoba o = new Osoba("Jan","Kowalski");
Przygotował: Jacek Sroka 21 Kapsułkowanie Kontrolowanie inicjalizacji nie wystarcza do zachowania spójności Co nam grozi? Osoba o = new Osoba("Jan","Kowalski"); // o.imię = null; o.nazwisko = null; Chcemy żeby obiekty były hermetycznymi kapsułkami
Przygotował: Jacek Sroka 22 Modyfikatory dostępu Dla atrybutów, metod, konstruktorów, klas i interfejsów public (dostęp publiczny) bez ograniczeń protected (dostęp chroniony) z pakietu i podklas (nawet w innym pakiecie) brak modyfikatora (dostęp domyślny) umożliwia dostęp z pakietu private (dostęp prywatny) z klasy zadeklarowanej na najwyższym poziomie struktury programu, w której jest zawarta (nie koniecznie bezpośrednio) deklaracja opatrzona tym modyfikatorem dostępu Inne modyfikatory: abstract (klasa, metoda), final (klasa, metoda, zmienna), native (metoda), static (metoda, atrybut), synchronized (metoda), volatile (zmienna), transient (atrybut), strictfp (klasa, metoda)
Przygotował: Jacek Sroka 23 Definicja klasy [modyfikator] class nazwa_klasy { [modyfikator] n_typu n_atr [=wyrażenie_inicjalizujące]; [modyfikator] typ_zwr nazwa_met([arg]) [klauzula_throw] { kod_metody
Przygotował: Jacek Sroka 24 Modyfikatory przykład package mój.pakiet1; import jakies.klasy.*; //kolejność definicji klas jest nieistotna public class Test { public static void main(string[] args) { Modyfikatory modyf = new Modyfikatory(); modyf.a = 1; modyf.b = 2; modyf.c = 3; //modyf.d = 4; //klasy mogą mieć jedynie dostęp pakietowy lub public class Modyfikatory { public int a; protected int b; int c; private int d;
Przygotował: Jacek Sroka 25 Modyfikatory przykład c.d. package mój.pakiet2; import jakies.klasy.*; public class Test { public static void main(string[] args) { inny.pakiet.modyfikatory modyf; modyf = new inny.pakiet.modyfikatory(); modyf.a = 1; //modyf.b = 2; //modyf.c = 3; //modyf.d = 4; ----------------------------------------------------------- package inny.pakiet; public class Modyfikatory { public int a; protected int b; int c; private int d;
Przygotował: Jacek Sroka 26 Modyfikatory c.d. Prawa dostępu dotyczą klas, a nie obiektów programowanie aspektowe Atrybuty zazwyczaj deklarujemy jako prywatne lub chronione Konwencja get, set, is Dostęp prywatny w całej klasie na najwyższym poziomie class Zewnętrzna { class Lokalna1 { private int i1; class Lokalna2{ int met(){return new Lokalna1().i1; Typ tablicowy jest dostępny tylko jak dostępny jest typ elementu Klasa lub interfejs z najwyższego poziomu mogą mieć jedynie dostęp publiczny lub domyślny pakietowy
Przygotował: Jacek Sroka 27 Narzędzia java, javac, javadoc Ant, Maven 2 JUnit