Java niezbędnik programisty spotkanie nr 10. Typy wyliczeniowe, auto. opakowywanie/odpakowywanie,...

Podobne dokumenty
Laboratorium 03: Podstawowe konstrukcje w języku Java [2h]

Programowanie obiektowe

Platformy Programistyczne Podstawy języka Java

Java niezbędnik programisty spotkanie nr 9. Java 2 Platform, Standard Edition 5.0

Aplikacje Internetowe. Najprostsza aplikacja. Komponenty Javy. Podstawy języka Java

JAVA. Platforma JSE: Środowiska programistyczne dla języka Java. Wstęp do programowania w języku obiektowym. Opracował: Andrzej Nowak

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

dziedziczenie - po nazwie klasy wystąpią słowa: extends nazwa_superklasy

Zofia Kruczkiewicz, Programowanie obiektowe - java, wykład 2 1

Wykład 2 Wybrane konstrukcje obiektowych języków programowania (1)

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

Polimorfizm, metody wirtualne i klasy abstrakcyjne

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Java: interfejsy i klasy wewnętrzne

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Dokumentacja do API Javy.

Język JAVA podstawy. Wykład 3, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

Wprowadzenie do języka Java

Programowanie obiektowe

Dziedziczenie. dr Jarosław Skaruz

Kurs programowania. Wykład 2. Wojciech Macyna. 17 marca 2016

Klasy abstrakcyjne, interfejsy i polimorfizm

KOTLIN. Język programowania dla Androida

Microsoft IT Academy kurs programowania

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

Języki i techniki programowania Ćwiczenia 2

Programowanie obiektowe

MATERIAŁY DO ZAJĘĆ II

Języki i metody programowania Java. Wykład 2 (część 2)

Java: kilka brakujących szczegółów i uniwersalna nadklasa Object

Java podstawy jęyka. Wykład 2. Klasy abstrakcyjne, Interfejsy, Klasy wewnętrzne, Anonimowe klasy wewnętrzne.

Język ludzki kod maszynowy

Podstawowe części projektu w Javie

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Programowanie obiektowe

Dawid Gierszewski Adam Hanasko

Metody Metody, parametry, zwracanie wartości

Akademia ETI. Wprowadzenie do programowania w Javie PG Java User Group Przemysław Kulesza

Klasy. dr Anna Łazińska, WMiI UŁ Podstawy języka Java 1 / 13

Wykład 6: Dziedziczenie

Kurs programowania. Wykład 9. Wojciech Macyna. 28 kwiecień 2016

Wyjątki. Streszczenie Celem wykładu jest omówienie tematyki wyjątków w Javie. Czas wykładu 45 minut.

Programowanie w Internecie. Java

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

Klasy i obiekty cz II

Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta Strona 1 z 26. Powrót. Full Screen. Zamknij.

Obiekt klasy jest definiowany poprzez jej składniki. Składnikami są różne zmienne oraz funkcje. Składniki opisują rzeczywisty stan obiektu.

ROZDZIAŁ 2. Operatory

10. Programowanie obiektowe w PHP5

Programowanie obiektowe

Języki Programowania II Wykład 3. Java podstawy. Przypomnienie

Wykład 4: Klasy i Metody

Programowanie obiektowe

Języki i metodyka programowania. Język C# pętle, sterowanie, wyjątki

Zad.30. Czy można utworzyć klasę, która implementuje oba interfejsy?

Polimorfizm a klasy generyczne w języku Java. Zdzisław Spławski 1

Programowanie obiektowe

Enkapsulacja, dziedziczenie, polimorfizm

1. Co będzie wynikiem wykonania poniŝszych instrukcji? g2d.gettransform().scale(1, -1); g2d.gettransform().translate(4, -8); g2d.drawline(4, 0, 4, 4);

Pętle. for, while, do... while, foreach. Materiał pomocniczy do kursu Podstawy programowania Autor: Grzegorz Góralski ggoralski.

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz

Informatyka I. Dziedziczenie. Nadpisanie metod. Klasy abstrakcyjne. Wskaźnik this. Metody i pola statyczne. dr inż. Andrzej Czerepicki

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Programowanie wieloplatformowe w Java

Java Język programowania

Programowanie w środowiskach graficznych. Wykład 3 Język C#

Rozdział 4 KLASY, OBIEKTY, METODY

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Programowanie obiektowe

Lista, Stos, Kolejka, Tablica Asocjacyjna

Kurs WWW. Paweł Rajba.

Kiedy potrzebne. Struktura (rekord) Struktura w języku C# Tablice struktur. struktura, kolekcja

Współbieżność w środowisku Java

Definiowanie własnych klas

Warunek wielokrotnego wyboru switch... case

Podstawy języka C++ Maciej Trzebiński. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. Praktyki studenckie na LHC IVedycja,2016r.

Wykład 5: Więcej o Klasach i Metodach

Interfejsy. Programowanie obiektowe. Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej

PHP 5 język obiektowy

Tworzenie aplikacji w języku Java

Typy złożone. Struktury, pola bitowe i unie. Programowanie Proceduralne 1

Programowanie w języku C++

Programowanie w języku Java

WSNHiD, Programowanie 2 Lab. 2 Język Java struktura programu, dziedziczenie, abstrakcja, polimorfizm, interfejsy

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

Typy sparametryzowane

Polimorfizm. dr Jarosław Skaruz

Kurs programowania. Wykład 3. Wojciech Macyna. 22 marca 2019

Wykład 8: klasy cz. 4

Przypomnienie o klasach i obiektach

Programowanie, algorytmy i struktury danych

Programowanie obiektowe

1. Co można powiedzieć o poniższym kodzie (zakładając, że zaimportowano wszystkie niezbędne klasy)?

Programowanie I C / C++ laboratorium 03 arytmetyka, operatory

Część 4 życie programu

Języki i metody programowania Java INF302W Wykład 2 (część 1)

Szablony funkcji i szablony klas

1 Podstawy c++ w pigułce.

Transkrypt:

Java niezbędnik programisty spotkanie nr 10 Typy wyliczeniowe, auto. opakowywanie/odpakowywanie,... 1

Jak nie należy implementować typu wyliczeniowego Opracował class Przedmiot1 { public static final int BD = 1; public static final int IO = 2; public static final int NIEZBĘDNIK = 3; public static final int XML = 4; public static final int J2EE = 5; //przykładowa metoda String dajnazwę(int i) { switch (i) { case 1: return "Bazy danych"; case 2: return "Inżynieria oprogramowania"; case 3: return "Java niezbędnik programisty"; case 4: return "XML i metody zarządzania treścią"; case 5: return "Java 2 Platform, Enterprise Edition"; default: String s = "Nie ma takiego przedmiotu: " + i; assert (true) : s; return s; 2

Wady/Zalety Zalety: Prostota! Kodowanie informacji przy pomocy masek bitowych (np. użycie kolejnych potęg 2). Jeżeli nie stworzyliśmy dziur w numeracji to łatwo iterować. Wady: Nie ma kontroli typów. Przedmioty przekazujemy jako wartości całkowite. Niestaranny programista może przez pomyłkę przekazać jako parametr inną stałą całkowitą, np. PowodyNaZawalenieNocy.DEBUGOWANIE_NIESTARANNEGO_KODU Nie zabraniamy przekazywania wprost wartości z pominięciem zdefiniowanych stałych, np. dajnazwe(3). Zawsze trzeba być przygotowanym, że ktoś przekaże wartość z poza zakresu, np. dajnazwe(13). Nie można łatwo zmienić numeracji. Wniosek: Nie wbijajmy gwoździ ręką. Zbudujemy sobie młotek! 3

Typy wyliczeniowe zrób to sam //żeby nam nikt nie zrobił dziwnych przedmiotów w podklasie final class Przedmiot2 { private int numer;//przyda się jak będziemy switchować public int getnumer() { return numer; private String pełnanazwa;//jedynie do odczytu String dajnazwę(przedmiot2 p) { return p.pełnanazwa; private Przedmiot2(int nr, String pn) {//ograniczona liczba egzemplarzy this.numer = nr; this.pełnanazwa = pn; public static final Przedmiot2 BD = new Przedmiot2(1, "Bazy danych"), IO = new Przedmiot2(2, "Inżynieria oprogramowania ); NIEZBĘDNIK = new Przedmiot2(3, "Java niezbędnik programisty ); XML = new Przedmiot2(4, "XML i metody zarządzania treścią ); J2EE = new Przedmiot2(5, "Java 2 Platform, Enterprise Edition ); 4

Wady/Zalety Zalety: Pełna kontrola typów. Posługujemy się egzemplarzami naszej klasy. Istnieją jedynie wyliczone przez nas egzemplarza. Nadal można switchować na opierając się na zaszytych wewnątrz wartościach całkowitych. Można wygodnie wprowadzać zmiany, np. w numeracji. Wady: Trzeba się najpierw dużo narobić. Ponieważ nie powinniśmy polegać na zaszytych wewnątrz wartościach całkowitych nie można kodować informacji przy pomocy masek bitowych. Chociaż przy odrobinie wysiłku można sobie poradzić przy pomocy zbiorów. Żeby iterować po możliwych wartościach trzeba się jeszcze bardziej narobić. 5

Typy wyliczeniowe w J2SE 5.0 Od wersji 5.0 młotek jest dołączony do Javy. Jest to wersja deluxe: ma wbudowaną poziomnicę, miarkę i latarkę, co więcej łatwo daje się integrować z pozostałymi narzędziami, np. obcęgami, wiertarką, wkręcarką, a nawet ekspresem do parzenia kawy, na szczęście w 90% przypadków do wbijania gwoździ wystarczy 10% funkcjonalności młotka. Mimo to lepiej przebrnąć przez instrukcję obsługi super młotka niż za każdym razem konstruować swój dopasowany do sytuacji zwłaszcza jeśli chcemy tworzyć zgrany zespół z innymi (jest o wiele bardziej prawdopodobne, że naszymi młotkami dadzą sobie po palcach) Dostarczanie młotków przez twórców języka jest zgodne ogólnie panującymi tendencjami, patrz: kolekcje, graficzny interfejs użytkownika, parsowanie XML,..., specyfikacje składające się na J2EE. 6

Przykład Już taki prosty kod chroni nas przed większością problemów, które mogły powstać przy wyliczaniu przy pomocy liczb całkowitych: enum Przedmiot { BD, IO, NIEZBĘDNIK, XML, J2EE //tutaj można dodać ; Co dostajemy za darmo: Przedmiot rozszerza java.lang.enum (która sama z siebie nie jest typem wyl.) Przedmiot to typ wyliczeniowy, a BD, IO, NIEZBĘDNIK, XML, J2EE to jego jedyne wartości (egzemplarze) nie można stworzyć innych egzemplarzy przedmiotu niż te wyliczone (brak publicznego konstruktora) typy wyliczeniowe są zawsze final (nie można użyć tego modyfikatora, ani abstract) wartości są zawsze public static final (nie można stosować żadnych modyfikatorów, nawet dostępu) 7

Co jeszcze dostajemy za darmo wartości można porównywać za pomocą == oraz equals() (wygodna praca z kolekcjami) typy wyliczeniowe implementują java.lang.comparable (wymuszone przez java.lang.enum) tostring() zwraca napis z nazwą wartości, a valueof() wartość na podstawie napisu z nazwą (np. Przedmiot.valueOf("BD") == Przedmiot.BD) ordinal() zwraca numer pozycji, w oparciu o kolejność deklaracji i poczynając od 0, ale jej używanie nie jest zalecane values() zwraca tablicę z wszystkimi wartościami 8

Przykład użycia System.out.print("W ofercie jest "+Przedmiot.values().length+" przedmiotów: "); for (Przedmiot p : Przedmiot.values()) System.out.print(p + ", "); W ofercie jest 5 przedmiotów: BD, IO, NIEZBĘDNIK, XML, J2EE, 9

switch static String pełnanazwa(przedmiot p ) { switch (p) { case BD: return "Bazy danych"; case IO: return "Inżynieria oprogramowania"; case NIEZBĘDNIK: return "Java niezbędnik programisty"; case XML: return "XML i metody zarządzania treścią"; case J2EE: return "Java 2 Platform, Enterprise Edition"; default: String s = "przedmiot "+p.tostring()+" nie był przewidziany"; assert (true) : s; return s; Wartości po case nie poprzedzamy (nie musimy i nie możemy) nazwą typu. Jak się da to wynik kompilacji takiego kodu będzie oparty na tablicy wartości funkcji ordinal(). Często typ wyliczeniowy i switch mogą być w różnych jednostkach kompilacji, więc wygenerowany kod może przypominać ciąg if/else. Warto pamiętać o rozsądnej klauzuli domyślnej, bo ktoś może zmienić definicję typu wyliczeniowego już po napisaniu switcha. 10

Wyliczenia wewnętrzne public class Test { enum Przedmiot {//można użyć modyfikatora static, ale jest nadmiarowy //tak jak abstract przy interfejsach BD, IO, NIEZBĘDNIK, XML, J2EE 11

Mapy //bardzo wydajna implementacja oparta na tablicy EnumMap<Przedmiot, String> pełnenazwy = new EnumMap<Przedmiot, String>(Przedmiot.class); pełnenazwy.put(przedmiot.bd, "Bazy danych"); pełnenazwy.put(przedmiot.io, "Inżynieria oprogramowania"); pełnenazwy.put(przedmiot.niezbędnik, "Java niezbędnik programisty"); pełnenazwy.put(przedmiot.xml, "XML i metody zarządzania treścią"); pełnenazwy.put(przedmiot.j2ee, "Java 2 Platform, Enterprise Edition"); System.out.print("Oto pełne nazwy wszystkich "+Przedmiot.values().length+" przedmiotów z oferty: "); for (Przedmiot p : Przedmiot.values()) System.out.println(p.toString()+" - "+pełnenazwy.get(p)); 12

Zbiory java.util.enumset (poniższe metody są statyczne i zwracają EnumSet) allof(class typ) zbiór z wszystkimi wartościami typu complementof(collection c) dopełnienie noneof(class typ) pusty zbiór o określonym typie elementów of(e e[, E e2, E e3, E e4, E e5]) zbiór z podanymi elementami of(e... e) wersja o zmiennej liczbie argumentów range(e from, E to) el. pewnego zakresu (na podstawie deklaracji typu) clone() kopia aktualnego (nie statyczna) zbioru oczywiście wszystkie normalne operacje na zbiorach są również dostępne 13

Integracja z ekspresem do kawy enum Przedmiot3 { BD("Bazy danych"), IO("Inżynieria oprogramowania"), NIEZBĘDNIK("Java niezbędnik programisty"), XML("XML i metody zarządzania treścią"), J2EE("Java 2 Platform, Enterprise Edition");//ten średnik jest potrzebny //konstruktor i tak jest prywatny, ale użycie modyfikatora jest dozwolone Przedmiot3(String pn) { this.pełnanazwa = pn; private String pełnanazwa; public String dajnazwę() { return pełnanazwa; 14

I inne kwiatki Typy wyliczeniowe mogą implementować interfejsy (jedną klasę już rozszerzają, mianowicie java.lang.enum). Dla zabezpieczenia się przed możliwością stworzenia jakiś dodatkowych egzemplarzy typy wyliczeniowe są oznaczone jako final. Można jednak trochę oszukać (chociaż więcej egzemplarzy się nadal nie da zrobić): num Przedmiot3 { BD("Bazy danych") {//zmusiliśmy typ wyliczeniowy do nie bycia final public String dajnazwę() { return "Teoria baz danych";, IO("Inżynieria oprogramowania"),... Mimo, że klasa Enum jest rozszerzana przez wszystkie typy wyliczeniowe samemu jej nie można rozszerzać: //class MójLepszyTypWyliczeniowy extends Enum { 15

Auto. opakowywanie/odpakowywanie Integer i = null; int j = i; //zgłosi NullPointerException Inkrementacja i dekrementacja działa, ale tworzony jest nowy obiekt Integer i = 1; Integer j = i; i++; System.out.println(i+" - "+(i == j)); //2 - false Należy uważać na porównywanie dwóch obiektów Integer i = 256; Integer j = 256; System.out.println(i == j); //false Ale uwaga nie zawsze tak będzie! JVM może zoptymalizować ten kod i stworzyć tylko jeden egzemplarz (bo przecież to i jego stan się nie zmienia). Dla wartość od -127 do 127 istnieje tylko po jednym egzemplarzu klasy opakowującej: Integer i = 13; Integer j = 13; System.out.println(i == j); //true Auto. opakowywanie/odpakowywanie działa również dla typu logicznego. 16

Operator ternarny wartośćlogiczna? wynikdlaprawdy : wynikdlafałszu Dotychczas wynikdlaprawdy i wynikdlafałszu musiały być tego samego typu lub jedna musiała się dawać przypisać na drugą. Od J2SE 5.0 wynik można zrzutować na wszystkie wspólne nadtypy obu wartości (zawsze wspólny będzie Object): true? new Float(1) : new Double(2) //w J2SE można zrzutować na Number Co więcej działa też auto. opakowywanie/odpakowywanie. np. jeżeli jedna wartość będzie typu Integer, a druga Float, to zostaną odpakowane i wynikiem będzie wartość typu float. 17

Uwaga Pomimo wygody auto. opakowywania/odpakowywani nie należy tracić czujności. Nie wolno zapominać, że wartość obiektów opakowujących się nie zmienia. To jest nieskończona pętla: Integer i = 0; int max = 10; while (i < max) { if (i < max-1) i++; System.out.println(i); A to nie: Integer i = 0; int max = 10; while (i < max) { if (i < max+1) i++; System.out.println(i); 18

Zagadka class ACoZPrzeciążaniem { public void coś(double x) { System.out.println("double"); public void coś(integer x) { System.out.println("Integer"); public static void test() { ACoZPrzeciążaniem a = new ACoZPrzeciążaniem(); int x = 1; a.coś(x); 19

Reguły dopasowywania metody Ze względu na zachowanie kompatybilności najpierw jest dobierana metoda zgodnie ze starymi regułami (J2SE 1.4). Jak się nie uda to próbowane jest auto. opakowywanie/odpakowywanie. Jak się nie uda to brane są pod uwagę metody ze zmienną ilością argumentów (dotychczas były ignorowane). 20

Metody ze zmienną liczbą argumentów Opracował Kompilator może za nas skonstruować tablicę z argumentów metody. class VarargsTest { public static void cześć(string...imiona) { System.out.print("Witaj "); for (String imie : imiona) System.out.print(imie+", "); VarargsTest.cześć("Alo", "Olu", "Ulu"); VarargsTest.cześć(new String[] {"Alo", "Olu", "Ulu"); VarargsTest.cześć(); //VarargsTest.cześć(null);//oczywiście NullPointerException W danej metodzie tą sztuczkę można użyć tylko raz, na końcu listy argumentów. Jeżeli pusta lista argumentów jest niedozwolona należy zgłaszać IllegalArgumentException 21

Metoda z dowolnymi parametrami public static void wypiszwszystko(object...dowypisania) { for (Object o : dowypisania) System.out.print(o+", "); wypiszwszystko(1, true, "ala", 1.); //jeżeli chcemy mieć taką wygodę trzeba użyć... public static void tablicojad(object[] dowypisania) { for (Object o : dowypisania) System.out.print(o+", "); //tablicojad(1, true, "ala", 1.); 22

Ale czy na pewno z dowolnymi? public static void wypiszwszystko(object...dowypisania) { for (Object o : dowypisania) System.out.print(o+", "); 23

Ale czy na pewno z dowolnymi? public static void wypiszwszystko(object...dowypisania) { for (Object o : dowypisania) System.out.print(o+", "); Tablica będąca jedynym argumentem zawsze będzie rozpakowana! Dlatego jak chcemy takową przekazać można ją opakować w tablicę:) albo zrzutować na Object 24