1 // Wczytywanie wierszy tekstu // trzeba dołączyć bibliotekę: import java.io.*; BufferedReader brin = new BufferedReader( new InputStreamReader (System.in) ); System.out.println("Początek wczytywania danych. ); String line = ; try{ while(! quit.equals(line)) { line = brin.readline(); System.out.println( Wprowadzony wiersz to: + line); System.out.println( Koniec wczytywania danych. ); catch(ioexception e) { System.out.println( Błąd podczas odczytu strumienia. );
2 // Wczytywanie liczb import java.io.*; public class Main{ public static void main(string[ ] args){ BufferedReader brin = new BufferedReader( new InputStreamReader(System.in) ); System.out.print( Wprowadz liczbe całkowita: ); String line = null; try{ line = brin.readline(); catch(ioexception e){ System.out.println( Błąd podczas odczytu strumienia. ); return; int liczba; try{ liczba = Integer.parseInt(line); catch(numberformatexception e){ System.out.print( Wprowadzona wartość nie jest liczbą całkowitą. ); return; int wynik = liczba * 2; System.out.println(liczba + * 2 = + wynik);
3 // Wczytywanie danych użycie klasy Stream Tokenizer import java.io.*; class Main{ public static void main(string[ ] args){ StreamTokenizer strtok = new StreamTokenizer( new BufferedReader( new InputStreamReader(System.in); ) ); System.out.print( Wprowadź liczbę: ); try{ while(strtok.nexttoken( )!= StreamTokenizer.TT_NUMBER){ System.out.println( To nie jest poprawna liczba. ); System.out.print( Wprowadź liczbę: ); catch(ioexception e){ System.out.print( Błąd podczas odczytu danych ze strumienia. ); return; double liczba = strtok.nval; double wynik = liczba * 2; System.out.println(liczba + * 2 = + wynik);
4 // Wczytywanie danych z użyciem klasy Scanner, która pojawiła się w // Java2 SE5 import java.util.*; public class Main { public static void main(string args[ ]) { String tekst = abc 1.24 12 ; Scanner scanner = new Scanner(tekst); while(!scanner.hasnextint( )){ System.out.print(scanner.next( )); System.out.println( nie jest wartością całkowitą. ); int value = scanner.nextint(); System.out.println(value + jest wartością całkowitą. ); int result = value * 2; System.out.println(value + * 2 = + result);
5 Klasy: Konstruktory class Pudelko { double szerokosc, wysokosc, glebokosc; //konstruktor pudelka Pudelko() { System.out.println( Budujemy pudelko ); szerokosc = 10; wysokosc = 10; glebokosc = 10; //oblicza objetosc pudelka double objetosc() { return szerokosc * wysokosc * glebokosc; public class Main { Pudelko mojepudelko1 = new Pudelko(); Pudelko mojepudelko2 = new Pudelko(); double objetosc; objetosc = mojepudelko1.objetosc(); System.out.println( Objetosc: + objetosc); objetosc = mojepudelko2.objetosc(); System.out.println( Objetosc: + objetosc);
6 Parametryzowany Konstruktor Wszystkie pudełka mają tą samą objętość. Potrzebujemy konstruktora, który tworzy pudełka różnych rozmiarów. class Pudelko { double szerokosc, wysokosc, glebokosc; //parametryzowany konstruktor pudelka Pudelko(double s, double w, double g) { szerokosc = s; wysokosc = w; glebokosc = g;... public class Main { Pudelko mojepudelko1 = new Pudelko(10, 20, 15); Pudelko mojepudelko2 = new Pudelko(3, 6, 9); double objetosc; objetosc = mojepudelko1.objetosc(); System.out.println( Objetosc: + objetosc); objetosc = mojepudelko2.objetosc(); System.out.println( Objetosc: + objetosc); Słowo Kluczowe this Odwołanie z metody do obiektu który ją wywołał. class Pudelko(double szerokosc, double wysokosc, double glebokosc) { this.szerokosc = szerokosc; this.wysokosc = wysokosc; this.glebokosc = glebokosc;
7 Przeciążanie Metod class Metody { void test() { System.out.println("Brak parametrow"); void test(int a) { System.out.println("a: " + a); void test(int a, int b) { System.out.println("a i b: " + a + " " + b); double test(double a) { System.out.println("double a: " + a); return a*a; public class PrzeciazanieMetod { Metody m = new Metody(); double wynik; m.test(); m.test(10); m.test(10, 20); wynik = m.test(12.5); System.out.println("test(12.5): " + wynik);
8 class Pudelko { Przeciążanie Konstruktorów Konstruktory z trzema parametrami, z jednym parametrem, i bez parametrów double szerokosc; double wysokosc; double glebokosc; // Obliczanie i wyświetlanie objętości: void objetosc() { System.out.println(szerokosc * wysokosc * glebokosc); Pudelko(double s, double w, double g) { szerokosc = s; wysokosc = w; glebokosc = g Pudelko(double b) { Pudelko() { szerokosc = wysokosc = glebokosc = b; szerokosc = wysokosc = glebokosc = -1; public class PrzeciazanieKonstruktorow { Pudelko p1 = new Pudelko(10,20,15); Pudelko p2 = new Pudelko(10); Pudelko p3 = new Pudelko(); p1.objetosc(); p2.objetosc(); p3.objetosc();
9 Przekazywanie Obiektów class Pudelko { double szerokosc; double wysokosc; double glebokosc; Pudelko(Pudelko p) { szerokosc = p.szerokosc; wysokosc = p.wysokosc; glebokosc = p.glebokosc;... public class PrzekazywanieObiektowKonstruktorom { Pudelko p1 = new Pudelko(10,20,30); Pudelko p2 = new Pudelko(p1); p1.objetosc(); p2.objetosc();
10 Rekursja Metoda rekurencyjna to metoda która wywołuje samą siebie (dla innych wartości argumentów): następuje alokacja pamięci na stosie dla zmiennych lokalnych i parametrów kod metody jest wywołany ponownie dla nowych wartości argumentów powrót powoduje usunięcie ze stosu parametrów i zmiennych, i kontynuację za punktem wywołania class Tablica { int wartosci []; Tablica(int i) { wartosci = new int[i]; void wyswietltablice(int i) { if (i == 0) return; else wyswietltablice(i-1); Demo: Rekursja i Tablice System.out.print( [ + (i-1) + ] ); System.out.println(wartosci[i-1]); public class RekursjaDlaTablic { Tablica t = new Tablica(10); int i; for (i=0; i<10; i++) t.wartosci[i] = i; t.wyswietltablice(10);
11 Kontrola Dostępu Cztery specyfikatory dostępu do elementów klasy: public dostępny dla każdej części programu private tylko dla składowych danej klasy default public dla składowych pakietu, gdzieznajduje się element, private dla reszty protected opisany będzie później Demo: Kontrola Dostępu class Test { int a; public int b; private int c; void zmienc(int i) { c = i; int zwrocc() { return c; public class KontrolaDostepu { Test t = new Test(); t.a = 10; t.b = 20; // t.c = 30!BLAD! t.zmienc(30); System.out.print( a, b i c: + t.a + ); System.out.println(t.b + + t.zwrocc());
12 Statyczne Składowe Klasy Normalnie, elementy klasy (pola i metody) mogą być tylko użyte poprzez obiekty tej klasy. Elementy statyczne są niezależne od obiektów klasy: statyczne dane static int dane; statyczna metoda static void metoda(); statyczny blok inicjalizacja elementów statycznych static {... Sposób wywołania: nazwaklasy.metoda() nazwaklasy.zmienna Ograniczenia: tylko odwołania do metod i danych statycznych nie mogą zawierać odwołań do this czy super Demo: Statyczne Składowe Klasy public class SkladoweStatyczne { static int a = 3; static int b; static void metoda(int x) { System.out.println( x = + x); System.out.println( a = + a); System.out.println( b = + b); //wykonywany raz gdy klasa jest ladowana static { System.out.println( Inicjalizacja ); b = a * 4 metoda(42);
13 Demo: Wywołanie Statyczne class Statyczne { static int a = 3; static int b = 99; static void wywolajmnie() { System.out.println( a = + a); public class WywolanieStatyczne { Statyczne.wywolajMnie(); System.out.println( b = ); System.out.print(Statyczne.b); Tablice jako Obiekty Tablica jest zaimplementowana jako obiekt. Jednym z atrybutów tego obiektu jest length: ilość elementów które tablica może zawierać. public class DlugoscTablicy { int a1[] = new int[10]; int a2[] = {3, 5, 7, 9, 11, 13, 15, 17; System.out.println( a1: + a1.length); System.out.println( a2: + a2.length);
14 Dziedziczenie Budowa jednej klasy na bazie drugiej, przez dodawanie/przesłanianie jej składowych: nad-klasa klasa bazowa pod-klasa klasa pochodna od bazowej class Pudelko { double szerokosc; double wysokosc; double glebokosc; Pudelko() { szerokosc = -1; wysokosc = -1; glebokosc = -1; double objetosc() { return szerokosc * wysokosc * glebokosc; class PudelkoPlus extends Pudelko { double ciezar; PudelkoPlus(double s, double c) { szerokosc = s; wysokosc = s; glebokosc = s; ciezar = c; class CiezarPudelka { PudelkoPlus p1 = new PudelkoPlus(10, 5.5); PudelkoPlus p2 = new PudelkoPlus(2, 0.5); double objetosc; objetosc = p1.objetosc(); System.out.println("Pierwsze: " + objetosc); objetosc = p2.objetosc(); System.out.println("Drugie: " + objetosc);
15 Odwołanie do Obiektu Podklasy Do zmiennej nad-klasy można przypisać odwołanie do obiektu dowolnej pod-klasy. class DziedziczenieOdwolanie { PudelkoPlus pp = new PudelkoPlus(10, 0.5); Pudelko p = new Pudelko(); double objetosc; objetosc = pp.objetosc(); System.out.println("Plus: " + objetosc); p = pp; objetosc = p.objetosc(); System.out.println("Pudelko: " + objetosc); Użycie Super jako Konstruktora Wywołanie konstruktora nad-klasy: super(lista-parametrow) Musi być pierwszą instrukcją konstruktora podklasy: class NadKlasa {... class PodKlasa extends NadKlasa { PodKlasa(...) { super(...);......
16 class Pudelko { double szerokosc; double wysokosc; double glebokosc; Użycie Super jako Konstruktora: Przykład Pudelko() { szerokosc = -1; wysokosc= - 1; glebokosc =-1; Pudelko(Pudelko p) { szerokosc = p.szerokosc; wysokosc = p.wysokosc; glebokosc = p.glebokosc;... class PudelkoPlus extends Pudelko { double ciezar; PudelkoPlus() { super(); ciezar = 0; PudelkoPlus(PudelkoPlus p) { super(p); ciezar = 0;... class SuperKonstruktor { PudelkoPlus pp1 = new PudelkoPlus(); PudelkoPlus pp2 = new PudelkoPlus(10, 5.5); PudelkoPlus pp3 = new PudelkoPlus(pp2); double objetosc; objetosc = pp1.objetosc(); System.out.println("Pierwsze " + objetosc); objetosc = pp2.objetosc(); System.out.println("Drugie " + objetosc); objetosc = pp3.objetosc(); System.out.println("Trzecie " + objetosc);
17 Jeden interfejs, wiele zachowań: Polimorfizm nad-klasa definiuje wspólne metody dla pod-klas pod-klasa dostarcza specyficzne implementacje dla niektórych z tych metod Swoboda definicji własnych metod przez pod-klase, pod rygorem zachowania interfejsu dla tych metod. Kombinacja dziedziczenia i przesłaniania: nad-klasa opisuje format metod realizowanych przez pod-klasę. class Figura { double d1; double d2; Figura(double a, double b) { d1 = a; d2 = b; double powierzchnia() { System.out.println("Niezdefiniowana"); return 0; class Prostokat extends Figura { Prostokat(double a, double b) { super(a, b); double powierzchnia() { System.out.println("Prostokat"); return d1 * d2;
18 class Trojkat extends Figura { Trojkat(double a, double b) { super(a, b); double powierzchnia() { System.out.println("Trojkat"); return d1 * d2 / 2; class Polimorfizm { Figura f = new Figura(10, 10); Prostokat p = new Prostokat(9, 5); Trojkat t = new Trojkat(10, 8); Figura r; r = p; System.out.println(r.powierzchnia()); r = t; System.out.println(r.powierzchnia()); r = f; System.out.println(r.powierzchnia());
19 Metody Abstrakcyjne Metoda dla której nie istnieje implementacja. abstract typ nazwa(lista-parametrow); Metody: konkretne - mogą być przesłonięte przez pod-klasy abstrakcyjne - muszą zostać przesłonięte Nie wolno definiować abstrakcyjnych konstruktorów, ani metod statycznych. Klasy Abstrakcyjne Klasa która posiada metody abstrakcyjne musi sama być deklarowana jako abstrakcyjna. abstract class {... Klasa abstrakcyjna nie posiada obiektów; nie wolno używać new na takiej klasie. Pod-klasa klasy abstrakcyjnej: implementuje wszystkie metody abstrakcyjne albo jest sama deklarowana jako abstrakcyjna. abstract class Figura { double d1; double d2; Klasy Abstrakcyjne: przykład Figura(double a, double b) { d1 = a; d2 = b; abstract double powierzchnia();
20 class Prostokat extends Figura { Prostokat(double a, double b) { super(a, b); double powierzchnia() { System.out.println("Prostokat"); return d1 * d2; class Trojkat extends Figura { Trojkat(double a, double b) { super(a, b); double powierzchnia() { System.out.println("Trojkat"); return d1 * d2 / 2; class AbstrakcyjnaFigura { // Nie wolno tworzyć obiektów klasy abstrakcyjnej: Figura f = new Figura(10, 10); Prostokat p = new Prostokat(9, 5); Trojkat t = new Trojkat(10, 8); // Wolno tworzyć odwołania do klasy abstrakcyjnej: Figura r; r=p; System.out.println(r.powierzchnia()); r=t; System.out.println(r.powierzchnia());
21 TWORZENIE I URUCHAMIANIE WĄTKÓW ( I ) Uruchamianiem i zarządzaniem działalnością wątku zajmuje się klasa Thread. Aby utworzyć wątek, należy utworzyć obiekt klasy Thread. Aby uruchomić wątek należy zastosować metodę start( ) wobec obiektu klasy Thread. Metoda start( ) wywołuje metodę run( ), w której podajemy działania (sekwencję instrukcji), które ma wykonywać wątek. Stad pierwszy sposób tworzenia i uruchamiania wątków: 1. Zdefiniować własną klasę dziedziczącą Thread. 2. Przedefiniować odziedziczoną metodę run( ), podając w niej działania, które ma wykonywać wątek. 3. Stworzyć obiekt naszej klasy, używając operatora new. 4. Wysłać mu komunikat start( ).
22 class NewThread extends Thread { NewThread() { super("demo Thread"); System.out.println("Watek potomny: " + this); start(); // Start the thread public void run() { try { for(int i = 5; i > 0; i--) { System.out.println("Watek potomny: " + i); Thread.sleep(500); catch (InterruptedException e) { System.out.println("Potomek przerwany."); System.out.println("Koniec watka potomnego."); class ExtendThread { new NewThread(); // create a new thread try { for(int i = 5; i > 0; i--) { System.out.println("Watek glowny: " + i); Thread.sleep(1000); catch (InterruptedException e) { System.out.println("Watek glowny przerwany."); System.out.println("Watek glowny zakonczony.");
23 TWORZENIE I URUCHAMIANIE WĄTKÓW ( II ) Sam wątek jest obiektem klasy implementującej interfejs Runnable. Interfejs ten zawiera deklarację metody run( ), która przy implementacji musi być zdefiniowana. Dlatego też drugim, preferowanym ze względu na lepszą możliwość izolacji kodu, sposobem tworzenia wątków jest implementacja w naszej własnej klasie interfejsu Runnable, a następnie po stworzeniu naszego obiektu dostarczenie referencji do niego jako argumentu konstruktora klasy Thread. Dodatkowo, sposób ten umożliwia dziedziczenie przez naszą klasę dowolnej innej klasy, gdyż już nie musimy dziedziczyć Thread. Stad drugi sposób tworzenia i uruchamiania wątków: 1. Zdefiniować własną klasę X dziedziczącą po klasie Y, implementującą interfejs Runnable: class X extends Y implements Runnable 2. Dostarczyć w niej definicji metody run. 3. Utworzyć obiekt naszej klasy: X x = new X ( ) ; 4. Utworzyć obiekt typu Thread, przekazując w konstruktorze referencję do naszej klasy x : Thread thread = new Thread (x); 5. Wywołać na rzecz tego obiektu metode start : thread.start( );
24 Tworzenie watków: Interfejs Runnable class NewThread implements Runnable { String name; // name of thread Thread t; NewThread(String threadname) { name = threadname; t = new Thread(this, name); System.out.println("New thread: " + t); t.start(); // Start the thread // This is the entry point for thread. public void run() { try { for(int i = 5; i > 0; i--) { System.out.println(name + ": " + i); Thread.sleep(1000); catch (InterruptedException e) { System.out.println(name + "Interrupted"); System.out.println(name + " zakonczony."); class MultiThreadDemo { new NewThread("Jeden"); // start threads new NewThread("Dwa"); new NewThread("Trzy"); try { // wait for other threads to end Thread.sleep(30000); catch (InterruptedException e) { System.out.println("Watek glowny przerwany"); System.out.println("Watek glowny zakonczony.");
25 Tworzenie watków: Interfejs Runnable class calka { private double a, b; private int l; public double wynik; calka(double a, double b, int l, double wynik) { this.a=a; this.b=b; this.l=l; this.wynik = wynik; public double funkcja_pod(double x) { return 4/(1+x*x); public double policz() { double h=(b-a)/l; double calka_l=0; for(int i=0;i<l;i++) { calka_l+=h*funkcja_pod(a+(i+0.5)*h); wynik=calka_l; return wynik; class Calka1 extends calka implements Runnable{ Thread t; Calka1 (double a, double b, int l, double wynik) { super(a, b, l, wynik); t = new Thread(this, "Calka1"); t.start();
26 public void run() { this.policz(); public void wyswietl() { System.out.println("Calka wynosi" + this.wynik); public class watki { public static void main(string[] args) { Calka1 tm = new Calka1(0.0,1.0,1000,0.0); // wait for threads to finish try { System.out.println("Czekam na zakonczenie"); tm.t.join(); catch (InterruptedException e) { System.out.println("Watek glowny zostal przerwany"); tm.wyswietl();
27 Zakończenie Wątku Metoda zwraca true, jeśli wątek, na której jest wywołana, wykonuje się: final boolean isalive() Metoda czeka aż wątek, na której wykonuje się, zakończy się: final void join() throws InterruptedException Przykład: class NewThread implements Runnable { String name; // name of thread Thread t; NewThread(String threadname) { name = threadname; t = new Thread(this, name); System.out.println("Nowy watek: " + t); t.start(); // Start watku public void run() { try { for(int i = 5; i > 0; i--) { System.out.println(name + ": " + i); Thread.sleep(1000); catch (InterruptedException e) { System.out.println(name + " zostal przerwany."); System.out.println(name + " zakonczony.");
28 class DemoJoin { NewThread ob1 = new NewThread("Jeden"); NewThread ob2 = new NewThread("Dwa"); NewThread ob3 = new NewThread("Trzy"); System.out.println("watek1" ob1.t.isalive()); System.out.println("watek2"ob2.t.isAlive()); System.out.println("watek3"ob3.t.isAlive()); // wait for threads to finish try { System.out.println("Czekam na zakonczenie"); ob1.t.join(); ob2.t.join(); ob3.t.join(); catch (InterruptedException e) { System.out.println("Watek glowny zostal przerwany"); System.out.println("watek1"+ob1.t.isAlive()); System.out.println("watek2"+ob2.t.isAlive()); System.out.println("watek3"ob3.t.isAlive()); System.out.println("Watek glowny zakonczony.");
29 Synchronizacja metod class KontoBankowe { private double StanKonta; KontoBankowe (double stan) { StanKonta = stan; public synchronized double PobierzStanKonta() { return StanKonta; public synchronized void ZwiekszStanKonta(double s) { StanKonta += s; class Klient extends Thread { private double Wplata; private KontoBankowe Konto; Klient (double w, KontoBankowe Konto) { Wplata = w; this.konto = Konto public void run() { for (int i = 0; i < 10; i++) Konto.ZwiekszStanKonta(Wplata); public class Bank1 { public static void main(string[]args) { KontoBankowe Konto= new KontoBankowe(0); Klient K1 = new Klient(7, Konto); Klient K2 = new Klient(10, Konto); K1.start(); K2.start(); try { K1.join(); K2.join(); catch (InterruptedException x) { ; System.out.println("Stan konta = " + Konto.PobierzStanKonta());
30 Synchronizacja bloków + zmienne statyczne (1) public class watki_static { static double tab[]; static double suma=0; static class suma_watek extends Thread{ private int numer; private int rozmiar; private double suma_l=0; suma_watek(int numer, int rozmiar) { this.numer = numer; this.rozmiar = rozmiar; public void run() { for (int i=0;i<rozmiar;i++) suma_l=suma_l+tab[numer*rozmiar+i]; synchronized (this) {suma=suma + suma_l; public static void main(string[] args) { tab = new double[200]; for (int i=0; i<200; i++) tab[i]=i; suma_watek tm1 = new suma_watek(0,100); suma_watek tm2 = new suma_watek(1,100); tm1.start(); tm2.start(); try { System.out.println("Czekam na zakonczenie"); tm1.join(); tm2.join(); catch (InterruptedException e) { System.out.println("Watek glowny zostal przerwany"); System.out.println("suma = " + suma); System.out.println("srednia = " + suma/199);
31 Synchronizacja bloków + zmienne statyczne (2) public class watki_static { static double tab[]; static double suma=0; static class suma_watek extends Thread{ private int numer; private int rozmiar; public static suma; private double suma_l=0; suma_watek(int numer, int rozmiar) { this.numer = numer; this.rozmiar = rozmiar; suma=0; public void run() { for (int i=0;i<rozmiar;i++) suma_l=suma_l+tab[numer*rozmiar+i]; synchronized (this) {suma=suma + suma_l; public static void main(string[] args) { tab = new double[200]; for (int i=0; i<200; i++) tab[i]=i; suma_watek tm1 = new suma_watek(0,100); suma_watek tm2 = new suma_watek(1,100); tm1.start(); tm2.start(); try { tm1.join(); tm2.join(); catch (InterruptedException e) { System.out.println("suma = " + tm1.suma); System.out.println("srednia = " + tm2.suma/199);
32 class Queue { WIELOWĄTKOWA IMPLEMENTACJA KOLEJKI // Pierwszy i ostatni element w kolejce Element head, tail; public synchronized void append (Element p) { if (tail = = null) else head = p; tail.next = p; p.next = null; tail = p; notify ( ); /* Poinformuj czekających o nowej wartości */ public synchronized Element get ( ) { try { while (head = = null) wait ( ); // Czekaj na element catch (InterruptedException e) { return null; Element p = head; // Zapamiętaj pierwszy element head = head.next; // Usuń go z kolejki if (head = = null) // Sprawdź, czy kolejka jest pusta tail = null; return p;