Przykłady programów w języku Java
Transkrypt
Przykłady programów w języku Java
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 { public static void main(String args[]) { 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 { public static void main(String args[]) { 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 { public static void main(String args[]) { 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 Przeciążanie Konstruktorów Konstruktory z trzema parametrami, z jednym parametrem, i bez parametrów class Pudelko { 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) { szerokosc = wysokosc = glebokosc = b; } Pudelko() { szerokosc = wysokosc = glebokosc = -1; } } public class PrzeciazanieKonstruktorow { public static void main(String args[]) { 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 { public static void main(String args[]) { 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 Demo: Rekursja i Tablice class Tablica { int wartosci []; Tablica(int i) { wartosci = new int[i]; } void wyswietlTablice(int i) { if (i == 0) return; else wyswietlTablice(i-1); System.out.print(“[“ + (i-1) + “] “); System.out.println(wartosci[i-1]); } } public class RekursjaDlaTablic { public static void main(String args[]) { 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 { public static void main(String args[]) { 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 } public static void main(String args[]) { 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 { public static void main(String args[]) { 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 { public static void main(String args[]) { 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 { public static void main(String args[]) { 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 { public static void main(String args[]) { 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 Użycie Super jako Konstruktora: Przykład class Pudelko { double szerokosc; double wysokosc; double glebokosc; 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 { public static void main(String args[]) { 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 Polimorfizm Jeden interfejs, wiele zachowań: ● 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 { public static void main(String args[]) { 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. Klasy Abstrakcyjne: przykład abstract class Figura { double d1; double d2; 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 { public static void main(String args[]) { // 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 { public static void main(String args[]) { 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 { public static void main(String args[]) { 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 { public static void main(String args[]) { 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 WIELOWĄTKOWA IMPLEMENTACJA KOLEJKI class Queue { // Pierwszy i ostatni element w kolejce Element head, tail; public synchronized void append (Element p) { if (tail = = null) head = p; else 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; } }