Programowanie Obiektowe Java Małgorzata Janik Zakład Fizyki Jądrowej malgorzata.janik@pw.edu.pl http://java.fizyka.pw.edu.pl/
Projekty Szczegoły na temat projektów można znaleźć na stronie: http://java.fizyka.pw.edu.pl/projekty Targi Pracyhttps://targipracyit.pl/PW IT 2/30
Powtórzenie Który element Javy sprawia, że stosunkowo łatwo odpalać programy na różnych platformach / systemach operacyjnych?
Maszyna Wirtualna
Pliki nagłówkowe W C/C++ używaliśmy plików nagłówkowych (.h lub.hpp) zawierające opis interfejsu modułu: Deklaracje zmiennych, funkcji, klas, itp. W Javie (ani w C#) nie występują.
Programowanie Obiektowe Trochę historii Programowanie Strukturalne Programowanie Zorientowane Obiektowo Zachowania i Atrybuty
Zamierzchła przeszłość Pierwsze komputery były programowane bezpośrednio z użyciem kodu maszynowego lub z wykorzystaniem asemblera. Pierwsze asemblery przypadają na połowę lat 50. Przykład kodu asemblera dla procesora Motorola 8-bit 6800 Przykład kodu maszynowego (kolumna druga rozpoczynająca się od 6C 36 00) Źródło: Wikipedia
Zamierzchła przeszłość Pierwsze komputery były programowane bezpośrednio z użyciem kodu maszynowego lub z wykorzystaniem asemblera. Pierwsze asemblery przypadają na połowę lat 50. Kontrola przepływu w programie odbywała się głównie przy pomocy warunkowych i bezwarunkowych instrukcji skoku. Instrukcja skoku (goto) pozwala na powtórne wykorzystanie tego samego fragmentu kodu ale sprawia też, że program jest zdecydowanie mniej czytelny. Fragmentu kodu w Perlu
Programowania radosne początki Jeżeli znamy podstawowe konstrukcje algorytmiczne i potrafimy je zagnieżdżać, wówczas teoretycznie jesteśmy w stanie napisać każdy algorytm. Jednakże, długość kodu programu nastaje się coraz większa i po pewnym czasie nie jesteśmy w stanie objąć wszystkiego wzrokiem i umysłem. Zastosowanie podprogramu (np. funkcji) pozwala podzielić algorytm na zbiór mniejszych, wydzielonych części.
Programowanie strukturalne Definicja: paradygmat programowania opierający się na podziale kodu źródłowego programu na procedury i hierarchicznie ułożone bloki. Rozwijał się w opozycji do programowania wykorzystującego proste instrukcje warunkowe i skoki (goto). Początki programowania strukturalnego przypadają na Lata 60. XX wieku, a ważnym głosem w dyskusji o programowaniu strukturalnym był list Edsgera Dijkstry z 1974 roku: Instrukcja goto powinna zostać usunięta z wszystkich wysokopoziomowych języków programowania (to znaczy z wszystkich poza - prawdopodobnie - czystym kodem maszynowym. Programowanie strukturalne zwiększa czytelność i ułatwia analizę programów, co stanowi znaczącą poprawę w stosunku do trudnego w utrzymaniu spaghetti code często wynikającego z użycia instrukcji goto.
Programowanie strukturalne Definicja: paradygmat programowania opierający się na podziale kodu źródłowego programu na procedury i hierarchicznie ułożone bloki. Rozwijał się w opozycji do programowania wykorzystującego proste instrukcje warunkowe i skoki (goto). Początki programowania strukturalnego przypadają na Lata 60. XX wieku, a ważnym głosem w dyskusji o programowaniu strukturalnym był list Edsgera Dijkstry z 1974 roku: Instrukcja goto powinna zostać usunięta z wszystkich wysokopoziomowych języków programowania (to znaczy z wszystkich poza - prawdopodobnie - czystym kodem maszynowym. Programowanie strukturalne zwiększa czytelność i ułatwia analizę programów, co stanowi znaczącą poprawę w stosunku do trudnego w utrzymaniu spaghetti code często wynikającego z użycia instrukcji goto. Spagetti code = trudny do zrozumienia kod źródłowy programu. Używano wielu instrukcji warunkowych i następnych w nich zagnieżdżonych konstrukcji GOTO. Droga przez kolejne rozkazy była tak poplątana, że odczytanie takiego kodu i zrozumienie go było bardzo uciążliwe, a ewentualne modyfikacje zwykle prowadziły do błędów w programie.
Programowanie strukturalne Programowanie strukturalne polega na tworzeniu programów wyłącznie w oparciu o trzy kompozycje algorytmiczne: Sekwencyjną (instrukcje wykonują się jedna po drugiej), Warunkową (instrukcje warunkowe if, if else, switch) Iteracyjną (pętle for, while, do while). Zabronione są algorytmy wykorzystujące instrukcję skoku (GOTO).
Problemy z programowaniem strukturalnym W przypadku programowania strukturalnego często mamy doczynienia z danymi,które muszą być widoczne w całym programie (dla wielu funkcji) i wiele funkcji może je zmieniać = tzw. dane globalne. W takim wypadku każda funkcja może zmienić dane, które mają wpływ na działanie wszystkich innych elementów prorgamu. Czyli jedna niewielka zmiana może popsuć działanie całego kodu w wielu różnych miejscach.
Problemy z programowaniem strukturalnym Koncepcja programowania obiektowego pierwotnie pojawiła się w Simuli 67, języku zaprojektowanym do zastosowań symulacyjnych, stworzonym przez Ole-Johana Dahla i Kristena Nygaarda z Norsk Regnesentral w Oslo. Mówi się, że pracowali oni nad symulacjami zachowania się statków i mieli kłopoty z opanowaniem wszystkich zależności, jakie wywierały na siebie nawzajem wszystkie parametry statków w symulacji. Wtedy wpadli na pomysł, by pogrupować typy statków w różne klasy obiektów, a każda z klas sama odpowiadałaby za określanie własnych danych i zachowań. Upraszczamy program, grupując kod w klasy, w których każda jest odpowiedzialna tylko za samą siebie (swoje dane i swoje funkcje) Programowanie obiektowe zyskało status techniki dominującej w połowie lat 80 (dzięki C++)
Programowanie Obiektowe Programy definiujemy za pomocą obiektów. Koncepcja obiektów fizycznych jest znana każdemu Możemy sobie wyobrazić samochód, człowieka, toster.
Programowanie Obiektowe Programy definiujemy za pomocą obiektów. Koncepcja obiektów fizycznych jest znana każdemu. Obiekty w programowaniu to są modele rzeczywistych obiektów fizycznych. Samochód Człowiek Toster - kolor ZIELONY - nazwisko EINSTEIN - producent HB - marka DAEWOO - zawód FIZYK - typ POP-UP + Tankuj() + Śpij() + Grzej() Programowanie+ Obiektowe (Wykład) Jedź() + GenerujNobla() + WyrzućTosty()
Programowanie Obiektowe Obiekty w programie reprezentują w pewnym stopniu obiekty rzeczywiste Jeśli chcemy zaprogramować aplikacje dla zarządzania szpitalem, zapewne będziemy musieli stworzyć obiekty odpowiadające pacjentom, lekarzom, pielęgniarkom, ochronie, W rzeczywistości to obiekty oddziałują ze sobą. W przypadku programów komputerowych jest podobnie: obiekty wysyłają do siebie wiadomości (wywołanie funkcji na innym obiekcie), a czasem uzyskują informacje zwrotne (zwracane zmienne).
Programowanie Obiektowe Na obiekty składają się atrybuty i zachowania: Toster Samochód - kolor ZIELONY - marka DAEWOO + Tankuj() + Jedź() atrybuty zachowania - producent HB - typ POP-UP + Grzej() + WyrzućTosty() Obiekty zawierają więc zarówno dane (wartości atrybutów) oraz zachowanie (możliwe akcje które dany obiekt może wykonać) zarówno - różnica między programowaniem proceduralnym a obiektowym
Programowanie Obiektowe Na obiekty składają się atrybuty i zachowania: Toster Samochód - kolor ZIELONY - marka DAEWOO + Tankuj() + Jedź() atrybuty zachowania - producent HB - typ POP-UP + Grzej() + WyrzućTosty() Dobrze zaprojektowany program zakłada, że wartości atrybutów nie może zmienić nic poza obiektem, do którego należą czyli wszystkie zmiany następują poprzez wywołanie odpowiednich zachowań (wywołanie funkcji) Enkapsulacja, metody Set i Get. Każdy obiekt odpowiada za swoje dane.
Atrybuty i ich wartości Należy pamiętać, że atrybut (pole składowe) i jego wartość, to dwie różne rzeczy : Samochód - kolor ZIELONY - marka DAEWOO atrybuty wartości atrybutów Każdy samochód będzie miał kolor, ale nie każdy będzie zielony. Sam atrybut jest jak pusta formatka, w którą możemy wpisywać wartości charakterystyczne dla naszego obiektu (konkretnej instancji naszej klasy).
Atrybuty i ich wartości Należy pamiętać, że atrybut (pole składowe) i jego wartość, to dwie różne rzeczy : Sam atrybut jest jak pusta formatka, w którą możemy wpisywać wartości charakterystyczne dla naszego obiektu (konkretnej instancji naszej klasy).
Zachowania i atrybuty na przykładzie public class Punkt { Punkt (double parametr1, double parametr2){ x = parametr1; y = parametr2; public String Wypisz(){ String text; text = "Wspolrzedne ("+ x + ", " + y + ")"; return text; double x, y; public static void main(string[] args) { Punkt p1 = new Punkt (30,30); System.out.println(p1.Wypisz());
Zachowania i atrybuty na przykładzie public class Punkt { Punkt (double parametr1, double parametr2){ x = parametr1; y = parametr2; public String Wypisz(){ String text; text = "Wspolrzedne ("+ x + ", " + y + ")"; return text; double x, y; public static void main(string[] args) { Punkt p1 = new Punkt (30,30); System.out.println(p1.Wypisz()); W programowaniu obiektowym klasa reprezentuje obiekty. Definicja klasy zwykle nie reprezentuje konkretnego obiektu, ale raczej typ.
Zachowania i atrybuty na przykładzie public class Punkt { Punkt (double parametr1, double parametr2){ x = parametr1; y = parametr2; public String Wypisz(){ String text; text = "Wspolrzedne ("+ x + ", " + y + ")"; return text; double x, y; public static void main(string[] args) { Punkt p1 = new Punkt (30,30); Instancja klasy = konkretny obiekt. System.out.println(p1.Wypisz());
Zachowania i atrybuty na przykładzie public class Punkt { Punkt (double parametr1, double parametr2){ x = parametr1; y = parametr2; public String Wypisz(){ String text; text = "Wspolrzedne ("+ x + ", " + y + ")"; return text; Atrybuty. double x, y; Zwykle nazywamy je polami (ang. fields). Nie powinny być dostępne z zewnątrz. public static void main(string[] args) { Punkt p1 = new Punkt (30,30); System.out.println(p1.Wypisz());
Zachowania i atrybuty na przykładzie public class Punkt { Punkt (double parametr1, double parametr2){ x = parametr1; y = parametr2; public String Wypisz(){ String text; text = "Wspolrzedne ("+ x + ", " + y + ")"; return text; double x, y; Zachowania / akcje, które możemy wywołać na naszym obiekcie. Np. utworzenie obiektu o konkretnych public static void main(string[] args) { wartościach atrybutów czy zwrócenie Punkt p1 = new Punkt (30,30); informacji o obiekcie w postaci napisu System.out.println(p1.Wypisz()); (String). Czyli funkcje składowe (metody).
Obiektowa Java vs. C++ W latach 90 to C++ był uważany za lidera programowania obiektowego. Ale C++ jest językiem hybrydowym : pozwala na programowanie strukturalne, bądź obiektowe, bądź miksowanie obu paradygmatów co w oczywisty sposób może prowadzić (i często prowadzi) do powstawania kodu który jest skomplikowany i trudny w utrzymaniu Java stworzona została od początku jako język służący do programowania obiektowego
Powtórzenie Struktura Programu Struktura Klasy Metody Dziedziczenie Oraz nowości Klasa Object Konstruktory i Super
Struktura programu package... //deklaracja pakietu, opcjonalna ale zalecana import... // deklaracje importu public class Punkt { //deklaracje konstruktorów Punkt (double parametr1, double parametr2){ x = parametr1; y = parametr2; //deklaracje metod public String Wypisz(){ String text; text = "Wspolrzedne ("+ x + ", " + y + ")"; return text; //deklaracje pól double x, y; public class KlasaStartowa { public static void main(string[] args) { Punkt p1 = new Punkt (30,30); System.out.println(p1.Wypisz()); //funkcja główna
Struktura klasy class NazwaKlasy { //deklaracje konstruktorów NazwaKlasy(lista parametrów){ //treść/zawartość konstruktora //deklaracje metod Typ1 metoda1(lista parametrów) { //treść/zawartość metody1 return obiekttyp1;... //deklaracje pól Typ pole1;... Typ polen;
Struktura klasy class NazwaKlasy { //deklaracje konstruktorów NazwaKlasy(lista parametrów){ //treść/zawartość konstruktora //deklaracje metod Typ1 metoda1(lista parametrów) { //treść/zawartość metody1 return obiekttyp1;... //deklaracje pól Typ pole1;... Typ polen; Metody = Funkcje składowe
Definiowanie metody [modyfikatory] TypZwracanejWartości nazwametody (TypArgumentu1 zmienna1,,typargumentun zmiennan) { TypZwracanejWartości zwracanawartość; // kod metody, w którym można korzystać ze zmiennych 1..N return zwracanawartość; // jeśli metoda void - nic nie zwraca Metody mogą być zadeklarowane bezpośrednio w klasie lub odziedziczone po nadklasach lub interfejsach.
Metody public class Punkt extends Object{ double x = 0, y = 0; Punkt (double parametr1, double parametr2){ x = parametr1; y = parametr2; void przesun(double parametr1, double parametr2){ x += parametr1; y += parametr2; double odlegloscodpoczatkuukladu(){ return Math.sqrt(x*x+y*y); String tostring(){ String text; text = "Wspolrzedne ("+ x + ", " + y + ")"; return text;
Korzystanie z utworzonych metod public class PunktTest2 { public static void main(string[] args) { Punkt p = new Punkt(0,0); int i=0; while (i<10){ p.przesun(5, 10); double d = p.odlegloscodpoczatkuukladu(); System.out.println(p + " Odległość od (0, 0): " + d); i++;
Struktura klasy class NazwaKlasy { //deklaracje konstruktorów NazwaKlasy(lista parametrów){ //treść/zawartość konstruktora //deklaracje metod Typ1 metoda1(lista parametrów) { //treść/zawartość metody1 return obiekttyp1;... //deklaracje pól Typ pole1;... Typ polen;
Struktura klasy [modyfikatory] class NazwaKlasy [extends NazwaKlasyNadrzednej] [implements NazwaInterfejsu] { //deklaracje konstruktorów NazwaKlasy(lista parametrów){ //treść/zawartość konstruktora //deklaracje metod Typ1 metoda1(lista parametrów) { //treść/zawartość metody1 return obiekttyp1;... //deklaracje pól Typ pole1;... Typ polen;
Struktura klasy [modyfikatory] class NazwaKlasy [extends NazwaKlasyNadrzednej] [implements NazwaInterfejsu] { //deklaracje konstruktorów NazwaKlasy(lista parametrów){ //treść/zawartość konstruktora //deklaracje metod Typ1 metoda1(lista parametrów) { //treść/zawartość metody1 return obiekttyp1;... //deklaracje pól Typ pole1;... Typ polen;
Struktura klasy [modyfikatory] class NazwaKlasy [extends NazwaKlasyNadrzednej] [implements NazwaInterfejsu] { //deklaracje konstruktorów extends oznacza dziedziczenie NazwaKlasy(lista parametrów){ = rozszerzenie klasy nadrzędnej //treść/zawartość konstruktora Możemy dziedziczyć po własnych klasach, albo tych zawartych w standardowym API. Jeśli chcemy uzyskać spersonalizowaną ramkę, dziedziczymy po JFrame. //deklaracje metod Jeśli chcemy uzyskać spersonalizowany przycisk, dziedziczymy po JButton. Typ1 metoda1(lista parametrów) { //treść/zawartość metody1 return obiekttyp1;... //deklaracje pól Typ pole1;... Typ polen;
Szybkie tworzenie klasy pochodnej w Eclipse 39/85
Dziedziczenie package pl.wyklad1.klasapokazowa; public class KlasaPrzykladowa { public class KlasaPochodna extends KlasaPrzykladowa { // deklaracje konstruktorów KlasaPrzykladowa() { x = 0; tekst = "domyslny"; public void wypisz() { System.out.println(x + " " + y + " " + tekst); int y = 10; // deklaracje metod public void wypisz() { System.out.println(x + " " + tekst); // deklaracje pól int x; String tekst; Klasa Nadrzędna Superclass Klasa Pochodna (podrzędna) Subclass
Szybkie tworzenie klasy (Object)
Struktura klasy [modyfikatory] class NazwaKlasy [extends NazwaKlasyBazowej] [implements NazwaInterfejsu] { //deklaracje konstruktorów extends oznacza dziedziczenie. NazwaKlasy(lista parametrów){ Możemy dziedziczyć po własnych klasach, //treść/zawartość konstruktora albo tych zawartych w standardowym API. Jeśli chcemy uzyskać ramkę, dziedziczymy po JFrame. //deklaracje metod Jeśli chcemy uzyskać przycisk, dziedziczymy po JButton. metoda1(lista parametrów) { Tworząc nową klasę w Javie zawsze używamy dziedziczenia. //treść/zawartość metody1 Jeśli nie napiszemy jawnie extends, return wobiekttyp1; takim wypadku dziedzicznymy po klasie Object. Typ1... //deklaracje pól Typ pole1;... Typ polen;
Przykład: public class Punkt { //konstruktor dwuargumentowy Punkt (double parametr1, double parametr2){ x = parametr1; y = parametr2; //pola double x = 0, y = 0; Nawet jeśli nie ma jawnego dziedziczenia, powstała klasa jest rozszrzerzeniem klasy Object http://docs.oracle.com/javase/7/docs/api/java/lang/object.html. Powyższa deklaracji klasy jest równoważna temu: public class Punkt extends Object { double x = 0, y = 0; Punkt (double parametr1, double parametr2){ x = parametr1; y = parametr2;
Klasa Object
Klasa Object
Przykład przedefiniowania (przeciążenia) metody tostring() odziedziczonej z klasy bazowej Object public class Punkt extends Object{ double x = 0, y = 0; Punkt (double parametr1, double parametr2){ x = parametr1; y = parametr2; public String tostring(){ String text; text = "Wspolrzedne ("+ x + ", " + y + ")"; return text;
Klasa Object
metoda equals() Służy ona do porównywania, czy dwa obiekty są sobie równe. Implementując metodę equals(), należy pamiętać o kilku zasadach metoda equals musi być zwrotna, czyli a.equals(a)==true. metoda equals musi być symetryczna, czyli a.equals(b)==b.equals(a). metoda equals musi być przechodnia, czyli jeżeli a.eqauls(b)==true i b.equals(c)==true to a.equals(c)==true. (Jednak gdy: a.equals(b)==false i b.equals(c)==false to a.equals(c) może być true) metoda equals musi być konsekwenta, czyli gdy dwa razy (w różnych chwilach czasu) porównujemy te same obiekty, to wynik tego porównania powinien być taki sam. obiekt jest nie równy null, czyli a.equals(null)==false dla każdego a nie będącego null To metoda, której powinniśmy używać porównując dwa obiekty. Np. dwa String-i: if (ala == Ala ) źle! if (ala.equals( Ala )) dobrze
Struktura klasy [modyfikatory] class NazwaKlasy [extends NazwaKlasyNadrzednej] [implements NazwaInterfejsu] { //deklaracje konstruktorów NazwaKlasy(lista parametrów){ //treść/zawartość konstruktora //deklaracje metod Typ1 metoda1(lista parametrów) { //treść/zawartość metody1 return obiekttyp1;... //deklaracje pól Typ pole1;... Typ polen; Konstruktory i dziedziczenie
Konstruktor Specjalna metoda danej klasy, wywoływana podczas tworzenia jej instancji. Podstawowym zadaniem konstruktora jest zainicjowanie obiektu. W C++/Javie: Nazywa się tak samo jak klasa Nic nie zwraca (brak napisu void przed nazwą) Może przyjmować: 0 parametrów (konstruktor domyślny / bezargumentowy) kilka parametrów (konstruktory z argumentami) Obiekt tej samej klasy (konstruktor kopiujący)
Konstruktory public class Punkt{ Punkt (){ x = 0; y = 0; Konstruktor domyślny Punkt (double parametr1, double parametr2){ x = parametr1; Konstruktor z y = parametr2; parametrami Punkt (Punkt p){ x = p.x; y = p.y; Konstruktor kopiujący double x, y;
Konstruktory i dziedziczenie super(p1, p2) jest równoważne z: new Punkt(p1,p2) public class Kolo extends Punkt { double promien = 0; public Kolo(double parametr1, double parametr2, double parametr3) { super(parametr1, parametr2); promien = parametr3; public Kolo(){ super(); promien = 10; Konstruktor bezargumentowy domyślne parametry klasy public Kolo (Punkt p, double parametr ){ super(p.x, p.y); promien = parametr; public Kolo(Kolo k){ super(k.x,k.y); promien = k.promien; Konstruktor kopiujący
Konstruktory i dziedziczenie public class Kolo extends Punkt { double promien = 0; public Kolo(double parametr1, double parametr2, double parametr3) { super(parametr1, parametr2); promien = parametr3; public Kolo(){ promien = 10; Uwaga, jeśli klasa Punkt nie miałaby żadnego konstruktora: OK. Java stworzyłaby pusty konstruktor domyślny dla klasy nadrzędnej. public Kolo (Punkt p, double parametr ){ super(p.x, p.y); promien = parametr; public Kolo(Kolo k){ super(k.x,k.y); promien = k.promien; Konstruktor kopiujący
Konstruktory i dziedziczenie public class Kolo extends Punkt { double promien = 0; public Kolo(double parametr1, double parametr2, double parametr3) { super(parametr1, parametr2); promien = parametr3; Uwaga, jeśli klasa Punkt nie miałaby konstruktora public Kolo(){ bezargumentowego, ALE miała inny konstruktor, promien = 10; pojawi się błąd: Implicit super constructor punkt() is undefined. public Kolo (Punkt p, double parametr ){ super(p.x, p.y); promien = parametr; public Kolo(Kolo k){ super(k.x,k.y); promien = k.promien; Konstruktor kopiujący
Konstruktory i dziedziczenie public class Kolo extends Punkt { double promien = 0; public Kolo(double parametr1, double parametr2, double parametr3) { super(parametr1, parametr2); promien = parametr3; public Kolo(){ super(0,0); promien = 10; public Kolo (Punkt p, double parametr ){ super(p.x, p.y); promien = parametr; public Kolo(Kolo k){ super(k.x,k.y); promien = k.promien; Konstruktor kopiujący
Użycie super jako Konstruktora Konstruktory nie są dziedziczone Wywołanie konstruktora nad-klasy: super(lista-parametrow) Musi być pierwszą instrukcją konstruktora podklasy: class NadKlasa {... class PodKlasa extends NadKlasa { PodKlasa(...) { super(...);...
Użycie konstruktorów public class KoloTest { public static void main(string[] args) { Kolo a,b,c,d,e; // Wykorzystanie różnych konstruktorów: a = new Kolo (10,10,5); b = new Kolo(); Punkt p1 = new Punkt (30,30); c = new Kolo (p1, 30); d = new Kolo (new Punkt(40,40), 40 ); e = new Kolo(c); System.out.println("" + a + "\n" + b + "\n"+ c + "\n" + d + "\n"+ e); // Jeśli klasa pochodna Kolo nie ma zdefiniowanej własnej metody // tostring() wykorzystywana jest metoda tostring klasy bazowej Punkt System.out.println(new Kolo(60,60,60)); // tworzenie "chwilowego" // obiektu bez referencji, na potrzeby wywołania metody
Odwołanie do Nadklasy przez super Odwołanie do elementu nad-klasy: super.pole super.metoda() Stosowane szczególnie gdy składowe podklasy przesłaniają składowe nad-klasy o tych samych nazwach.
Użycie super w metodach public class Superclass { public void printmethod() { System.out.println("Wypisano w nadklasie."); Jeśli nadpiszemy metodę z nadklasy, ale nadal chcemy ją wykorzystać, możemy użyć słowa kluczowego super. public class Subclass extends Superclass { // przeciąża (nadpisuje) metodę z nadklasy public void printmethod() { super.printmethod(); System.out.println("Wypisano w podklasie"); public static void main(string[] args) { Subclass s = new Subclass(); s.printmethod(); Efekt: Wypisano w nadklasie. Wypisano w podklasie.
Szybkie tworzenie klasy pochodnej w Eclipse Stwórz metody: Konstruktory z klasy nadrzędnej 60/85
Konstruktory z klasy nadrzędnej public class ZamykaneOkienko extends JFrame { public ZamykaneOkienko() throws HeadlessException { public ZamykaneOkienko(GraphicsConfiguration arg0) { super(arg0); public ZamykaneOkienko(String arg0) throws HeadlessException { super(arg0); public ZamykaneOkienko(String arg0, GraphicsConfiguration arg1) { super(arg0, arg1); Konstruktory klasy nadrzędnej dodane przez Eclipse a /** * @param args */ public static void main(string[] args) { ZamykaneOkienko zo = new ZamykaneOkienko(); zo.setvisible(true); 61/85
Konstruktory z klasy nadrzędnej public class ZamykaneOkienko extends JFrame { public ZamykaneOkienko() throws HeadlessException { this.setsize(640,480); setdefaultcloseoperation(exit_on_close); public ZamykaneOkienko(GraphicsConfiguration arg0) { super(arg0); this.setsize(640,480); setdefaultcloseoperation(exit_on_close); Nasze rozszerzenie klasy nadrzędnej: konkretne ustawienia, dodatkowe elementy. public ZamykaneOkienko(String arg0) throws HeadlessException { super(arg0); this.setsize(640,480); setdefaultcloseoperation(exit_on_close); Konstruktory klasy nadrzędnej dodane przez Eclipse a public ZamykaneOkienko(String arg0, GraphicsConfiguration arg1) { super(arg0, arg1); this.setsize(640,480); setdefaultcloseoperation(exit_on_close); /** * @param args */ public static void main(string[] args) { ZamykaneOkienko zo = new ZamykaneOkienko(); zo.setvisible(true); 62/85
Szybkie tworzenie klasy pochodnej w Eclipse 63/85
Szybkie tworzenie klasy pochodnej w Eclipse Metody abstrakcyjne (w C++ mówiliśmy czysto wirtualne ) to metody niedokończone. Jeśli klasa nadrzędna ma takie metody, to musimy je dokończyć w klasie podrzędnej, by móc stworzyć obiekt danej klasy Eclipse pomaga nam w tym przygotowując odpowiedni kod. Jeśli dana klasa nadrzędna nie ma takiej metody, zaznaczenie checkbox a nic nie zmieni. 64/85
Przygotowanie do laboratorium Komponenty w Javie Podpowiedzi Eclipse a Layout Manager
Komponenty Okienka: JFrame lub JFrame frame = new JFrame(); frame.setsize(640, 480); Frame.setDefaultCloseOperation(EXIT_ON_CLOSE); frame.setvisible(true); public class MyFrame extends JFrame { public MyFrame() { this.setsize(640,480); setdefaultcloseoperation(exit_on_close); public static void main(string[] args) { MyFrame mf = new MyFrame(); mf.setvisible(true); (zalecane) Dla domyślnego okna naciśnięcie [X] nie powoduje zamkniecia aplikacji. Aby to zmienić, należy wywołać metodę setdefaultcloseoperation(). 66/85
SetDefaultCloseOperation() EXIT_ON_CLOSE DISPOSE_ON_CLOSE zamyka aplikację zamyka ramke, usuwa obiekt reprezentujacy ramke, ale pozostawia pracujaca aplikację DO_NOTHING_ON_CLOSE nic nie robi (pozostawia ramke otwarta i kontynuuje prace aplikacji) HIDE_ON_CLOSE ukrywa ramke pozostawiajac pracujaca aplikacje (domyślne) 67/85
Komponenty Okienka: JFrame JFrame frame = new JFrame(); frame.setsize(640, 480); frame.setvisible(true); lub public class MyFrame extends JFrame { public MyFrame() { this.setsize(640,480); public static void main(string[] args) { MyFrame mf = new MyFrame(); mf.setvisible(true); (zalecane) Kontener: JPanel JPanel panel = new JPanel(); lub public class MyPanel extends JPanel {... public static void main(string[] args) { MyPanel mp = new MyPanel(); 68/85
Komponenty Guzik: JButton JButton buttonok = new JButton("OK"); panel.add(buttonok); JLabel label = new JLabel("To jest etykieta"); panel.add(label); Etykieta: JLabel JTextField field = new JTextField("To jest pole tekstowe"); panel.add(field); Pole tekstowe: JTextField 69/85
Dodawanie komponentu utworzenie komponentu (obiektu pewnej klasy) oraz ustawienie jego właściwości określenie kontenera pośredniego panelu z zawartością (ang. content pane) - czasem wywołanie metody add() kontenera lub kontenera pośredniego Komponent komponent = new Komponent(arg); kontener.add(komponent) Kontener (np. JPanel) to także rodzaj komponentu, i może być dodany jako element innego kontenera panelglowny.add(panelmniejszy) JButton button1 = new JButton("OK"); panel.add(button1); 70/85
Okno z przyciskiem 71/85
Podpowiedzi Eclipse a Pamiętajcie o możliwości naciśnięcia ikonki błedu po lewej stronie, żeby: Dodać odpowiednie klasy (import-y) Uzyskać podpowiedź jak naprawić błąd Jeśli szukacie odpowiedniej metody, zawsze warto nacisnąć kropkę i przejrzeć listę dostępnych funkcji Listę można też przywołać naciskając CTRL + spacja https://help.eclipse.org 72/85
Kontrolki Swing JButton JCheckBox JComboBox JList JMenu JRadioButton JSlider JSpinner JTextField JPasswordField 73/85
Kontrolki do wyświetlania informacji oraz kontrolki najwyższego poziomu JLabel JPanel JProgressBar JScrollPane JSeparator JSplitPane JToolTip JTabbedPane JToolBar JInternalFrame JLayeredPane RootPane 74/85
Rozmieszczanie komponenetów Layout Manager Sposób rozmieszczenia komponentów zależny od zarządcy układu (Layout Manager) Zastosowanie zarządcy układu w kontenerze metoda setlayout() Predefiniowani zarządcy układu ciągły FlowLayout siatkowy - GridLayout brzegowy BorderLayout kartowy CardLayout torebkowy - GridBagLayout pudełkowy BoxLayout wiosenny SpringLayout grupowy - GroupLayout 75/85
Layout Manager FlowLayout Najprostszy layout manager i domyślny dla każdego JPanel u. Wrzuca komponenty jeden po drugim do pojedynczego wiersza. Jeśli zabraknie miejsca w danym wierszu, wrzuca do kolejnego. Umieszczenie komponentów zależy od rozmiaru kontenera, więc nie możemy jasno określić, w którym dokładnie miejscu wyląduje nasz guzik. https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html 76/85
Layout Manager GridLayout GridLayout ustala ten sam rozmiar dla wszystkich komponentów po czym wrzuca je w siatkę o określonej ilości kolumn i wierszy. http://www.thaicreate.com/java/java-gui-layout-gridlayout.html 77/85
Layout Manager BorderLayout Możliwe składniki: PAGE_START LINE_START CENTER LINE_END PAGE_END Wygodne do robienia np. menu po lewej stronie albo nagłówka i stopki. Nie wszystkie składniki muszą być dodane 78/85
Layout Manager W ramach osobnych paneli można zastosować różne typ zarządzania rozmieszczeniem komponentów BorderLayout (gówny, lewy i centrum) + 2 x GridLayout BorderLayout + GridLayout ( 4 x 3 ) + GridLayout ( 5 x 1 ) + FlowLayout 79/85
Layout Manager W ramach osobnych paneli można zastosować różne typ zarządzania rozmieszczeniem komponentów BorderLayout (gówny, lewy i centrum) + 2 x GridLayout BorderLayout + GridLayout ( 4 x 3 ) + GridLayout ( 5 x 1 ) + FlowLayout 80/85
Użycie LM JPanel panel1 = new JPanel(new FlowLayout()); JPanel panel2 = new JPanel(new BorderLayout()); panel1.add(acomponent1); panel2.add(acomponent2, BorderLayout.PAGE_START); Można też dawać wskazówki co do wielkości komponentów wywołując metody na konkretnych komponentach setminimumsize, setpreferredsize, and setmaximumsize. np. component.setmaximumsize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE)); https://docs.oracle.com/javase/tutorial/uiswing/layout/using.html 81/85
Rozmiary komponentów Silnie zależą od użytego Layout Managera 82/85
Dziękuję za Uwagę! Do zobaczenia za tydzień. Porozmawiamy o interfejsach i obsłudze zdarzeń. m.in. jak oprogramować używanie guzików 83/85