115
Zaawansowane programowanie obiektowe Wyklad 1 JAVA

Zaawansowane programowanie obiektowe - kgrudzi - …kgrudzi.kis.p.lodz.pl/zpo/ZPO/ZPO/wyklad_files/_zpo_1.pdfStruktura programu -uwagi Program mo Ŝe by ćzapisany w jednym lub wielu

  • Upload
    phungtu

  • View
    212

  • Download
    0

Embed Size (px)

Citation preview

Zaawansowane programowanie obiektowe

Wykład 1

JAVA

Język java

� Rok 1990, Bill Joy:� „utworzenie obiektowego środowiska w oparciu o

C++”

� Język OAK (Object Application Kernel), 1991� Projekt Green,

James Gosling, Patrick Naughton, Mike Sheridan

Środowisko Java

� Obiektowy język java (podobieństwo do C++);� Nazwa pliku źródłowego nazwa.java (nazwa –

to nazwa klasy – publicznej -zdefiniowanej w pliku);

� Kompilator: *.java � kod B: *.class;� Maszyna wirtualna (JVM);� Tworzenie kodu wykonywalnego „w locie”

Just-In-Time� Biblioteka Javy.

Usytuowanie systemu Java

Przetwarzanie programów uŜytkownika

Cechy języka Java

� automatyczne odśmiecanie (garbage collection)

� nie dopuszcza arytmetyki wskaźnikowej� ścisła kontrola typów (konwersje)� obsługa wyjątków� wbudowane elementy współbieŜności

Przykład

� Programem w języku Java jest aplikacja(application) lub aplet (applet).

� Aplikacja jest programem samodzielnym, zaś aplet jest programem wbudowanym (np. w przeglądarkęWWW).

� KaŜda aplikacja musi zawierać dokładnie jeden moduł źródłowy nazywany modułem głównymaplikacji, którego klasa zawiera publiczną funkcjęklasy

Przykład

� public class Hello {public static void main(String args[]){System.out.print("Hello, World!\n");} //end main

} // end Hello

Kompilacja

� javac Hello.java � B-kod: Hello.class

� Interpretator:� java Hello

Jak działa interpretator?

� wyszuka plik o nazwie Hello.class , � czy klasa Hello zawiera publiczn ą metod ę

statyczn ą main� wykona instrukcje zawarte w bloku main. � W języku Java kaŜda instrukcja kończy sięśrednikiem, który pełni rolę symbolu terminalnego.

Jak działa interpretator?

� do metody main jako parametr jest przekazywana (z wiersza rozkazowego) tablica obiektów (łańcuchów) klasy String ; metoda main nie zwraca wyniku (typem zwracanym jest void );

� Ciało main zawiera jedną instrukcję;

� System.out.print("Hello, World!\n");

Jak działa interpretator?

� Słowo System jest nazwą klasy w standardowym środowisku języka.

� Klasa System zawiera statyczny obiekt składowy typu PrintStream o nazwie out

� wywołanie System.out oznacza pisanie do standardowego strumienia wyjściowego.

� Klasa PrintStream zawiera szereg przeci ąŜeńmetody o nazwie print (tu:parametr typu String).

� Kompilator automatycznie konwertuje"Hello, World\n" � obiekt klasy String;

� odnośnik (referencja ) do tego obiektu jest przekazywana do metody System.out.print().

� Metoda print() generuje jeden wiersz wyjściowy i powraca do metody main, która kończy wykonanie.

!!!

� w języku Java wszystkie stałe, zmienne i funkcje są elementami składowymi klas ;

� nie ma wielko ści globalnych , definiowanych poza klasą.

� nie deklaruje się metod (funkcji) składowych jako rozwijalnych (inline) bądź nie –decyzja naleŜy do kompilatora.

package moje.aplikacje;

import javax.swing.*;import java.awt.Container;

class PierwszyGUI extends JFrame{

public PierwszyGUI (){

...}

}

class KlasaStartowa{

PierwszyGUI ob1;PierwszyGUI ob2 = new PierwszyGUI ();

public static void main (String[] args){

...}

}

Określenie nazwy pakietu, do którego naleŜąklasy zdefiniowane w tym pliku. MoŜna opuścić.

Zewnętrzne pakiety (ew. pojedyncze klasy lub interfejsy), z których korzystamy w naszym programie. MoŜna uwaŜać ten element jako odpowiednik dyrektywy #include w C/C++.

Definicje klas (klasy mogą dziedziczyć, jak w tym przykładzie).

Metoda main klasy startowej. To od niej rozpoczyna się wykonywanie aplikacji. Musi być to metoda public static !

Inna klasa. Posiada składniki, które mogą być inicjalizowane.

Definicja konstruktora.

Aplikacja graficzna

import javax.swing.*;

class GUI extends JFrame{

public static void main (String[] args){

GUI gui = new GUI ();gui.setSize (300, 200);gui.show ();

} }

Klasa z metodą main dziedzicząca z klasy JFrame (opisującej okienko graficzne), która pochodzi z pakietu javax.swing . Korzysta z najprostszych odziedziczonych metod.

Struktura programu

package ... // deklaracja pakietu (niekonieczna)import ... // deklaracje importu; zwykle, a1e nie zawsze potrzebn eimport .../** Komentarz dokumentacyjnyzaczyna si ę uko śnikiem z dwoma gwiazdkami, ko ńczy gwiazdk ą i uko śnikiem*/// To jest klasa A <- to jest komentarzpublic class A{. . . }/* To jest komentarz wielowierszowy*/// To jest klasa B class B {......}

Struktura programu - uwagi

�Program moŜe być zapisany w jednym lub wielu plikachźródłowych (.java);

�wszystkie klasy składające się na program moŜnaumieścić w jednym pliku albo kaŜdą klasę moŜna umieścićw odrębnym pliku;

�w jednym pliku .java moŜe się znajdować tylko jednaklasa publiczna;

�jeśli w pliku .java znajduje się klasa publiczna, to plikmusi mieć dokładnie taka samą nazwę, jak ta klasa.

Struktura programu - Aplikacja:

�jedna z klas musi zawierać metodę public static void main(String[] args),

�Przykład:a.klasa Work i klasa Inna zdefiniowane w pliku

Work.java

b.po kompilacji dwa pliki: Work.class, Inna.class.

c.Wywołujemy: java Work [argumenty]

Klasy (przypomnienie)

� class nazwy klasy� {

� Ciało klasy� }

� Przed słowem kluczowym class moŜe wystąpić jeden ze specyfikatorów:

� abstract , public , final , lub� dwa z nich:

� np. public abstract, public final.

� Abstract : klasa abstrakcyjna nie moŜe wystąpić;

� final : klasa nie moŜe mieć podklas;

� Brak specyfikatora :klasa dostępna tylko dla tego pakietu;

� Po nazwie klasy mogą wystąpić frazy: a) ‘extends nazwa_superklasy’b) ‘implements nazwy_interfejsów’.

� a) klasa dziedziczy publicznie (zawsze) od klasy superklasa.

� b) w danej klasie zostaną zdefiniowane metody, zadeklarowane w implementowanych interfejsach.

� W języku Java kaŜda klasa dziedziczy od predefiniowanej klasy Object.

� Zatem, jeŜeli w definicji klasy nie występuje fraza extends, to jest to równowaŜne niejawnemu wystąpieniu w tej definicji frazy ‘extends Object’.

� oprócz słowa kluczowego class i nazwy klasywszystkie pozostałe elementy w deklaracji klasy sąopcjonalne .

� kompilator przyjmie domyślnie, Ŝe klasa jest niepubliczn ą, nieabstrakcyjn ą i niefinaln ąpodklasą predefiniowanej klasy Object .

Przykład

� public class Point { int x, y; }równowa Ŝne

� public class Point { int x, y; public Point() { super(); } }

przykład

� class Point {int x,y; Point() {x=1; y=2;}}� class CPoint extends Point {public int color =

0xFF00FF;}� public class Super1 {� public static void main(String args[]){� CPoint cp=new CPoint();� System.out.println("cp.color="+cp.color);� System.out.println("cp.x="+cp.x);� }//end main� }//end Super1

Interfejs

interface nazwa {/* Deklaracje metod i definicje stałych */

}

Interfejsy

Implementacja interfejsu w klasie to zdefiniowaniew tej klasie wszystkich! metod interfejsu.

Interfejs (deklarowany za pomocą słowa kluczowego interface) to:

•zestaw publicznych abstrakcyjnych metod, (domyślnie – nie trzeba pisać abstract)

•oraz ewentualnie statycznych stałych, (domyślnie – nie trzeba pisać final static)

Interfejs klasy – jest to jakby uboŜsza wersja klasy, oznacza zestaw metod i zastępuje wielodziedziczenie. Klasa moŜe mieć kilka interfejsów

Interfejsy

interface Speakable {int QUIET = 0; int LOUD = 1;String getVoice( int voice);

}

interface Moveable {void startMoving();void stopMoving();

}

class Pies extends Zwierz implements Speakable, Moveable { Pies () {}Pies(String s) { super (s); } String getTyp(){ return "Pies" ; } public String getVoice( int voice) {

if (voice == LOUD) return "HAU... HAU... HAU... " ;else return "hau... hau..." ;

} public void startMoving() {

System.out.println( "Pies " + name + "biegnie" );} public void stopMoving() {

System.out.println( "Pies " + name + "stan ął" );}

}

Interfejsy

Pies kuba = new Pies( "Kuba" );kuba.startMoving();System.out.println(kuba.getVoice(Speakable.LOUD));kuba.stopMoving();

void Wyscig(Moveable[] objects){

for ( int i =0; i < objects.length; i++)objects[i].startMoving();

}Wyscig(

new Moveable[] {new Pies(),new Samochod(),new Kot(),new Rower()

} );

Pakiety

Przykład 2:Java.awt.Button b = new Java.awt.Button( "0k" );

Przykład 4:import java.awt.*; // importuje wszystkie nazwy klas pakietu java.awtclass A {

Frame f = new Frame( "Tytu ł" ); // teraz mo Ŝemy uŜyć te Ŝ prostej nazwy klasyButton b = new Button( "0k" ); // teraz mo Ŝemy uŜyć te Ŝ prostej nazwy klasy

}Pakiet java.lang nie wymaga importu (m.in. zawiera klasy String i System).

Przykład 3:import java.awt.Button; // importuje nazw ę klasy Java.awt.Buttonclass A {

java.awt.Frame f = new java.awt.Frame( "Tytu ł" );Button b = new Button( "Ok" );

}

Przykład 1:package moj_pakiet;

Definiowanie klas•Dane są reprezentowane przezpola klasy•Operacje wprowadzamy poprzez definicjemetodklasy.•Zestaw metod klasy nazywany jest jejinterfejsem. •W Javie argumenty przekazywane są metodom wyłącznieprzez wartość.

void przestawPary(Parapl, Para p2) {

Para temp = pl;pl = p2;p2 = temp;

}

void incr( int x) {

++x;}

Konstruktory – moŜna przeciąŜać, istnieje konstruktor domyślny dopóki nie zdefiniujemy własnego

class Para { int a, b;Para( int x) {

a = x;b = x;

}}

class Para { int a, b;Para( int x, int y) {

a = x; b = y;

}}

Komunikacja z obiektami

Przykład 1:TypObiektu identyfikator = new NazwaKlasy(argumenty);

Przykład 4:void add(Para p) {

a = a + p.a ;b = b + p.b;

}

Przykład 2:TypObiektu identyfikator;identyfikator = new NazwaKlasy(argumenty);Para x = new Para(1,3); // Tworzy obiekt klasy Para// za pomoc ą konstruktora Para(int, int)

Przykład3:Para pl = new Para(l,2);// utworzenie nowego obiektu typu Para, pl - referencja d o niegoPara p2 = new Para(3,4);// utworzenie nowego obiektu typu Para, p2 - referencja d o niego

Słowo kluczowe this

SYTUACJA 1class Para {

int a;int b;void add( int a, int b){

this .a + = a ;this .b + = b;

}}

p.add(p1).add(p2).add(p3);co jest inną formą zapisu:p.add(p1);p.add(p2);p.add(p3);

SYTUACJA 2Para add(Para p){

a = a + p.a ;b = b + p. b;return this ;

}

SYTUACJA 3:patrz wywołanie konstruktora z innego konstruktora

Składowe statyczne

Uwaga: Ze statycznych metod nie wolno odwoływać się do niestatycznych składowychklasy (obiekt moŜe nie istnieć). MoŜliwe są natomiast odwołania do innych statycznychskładowych.Przykład: statyczne pole i metoda

Para p1 = null ,p2 = null ; . . . . . .if ( Para.count == 0)

Para p1 = new Para(1,1);else

while (Para.count < 10){

p2 = new Para(2,2);p1.add(p2);

}System.out.println( p1.count );Para.showCount ();p1.showCount ();p2.showCount ();

class Para{static int count = 0;Para( int x, int y){

count++;a = x; b = y;

}static void showCount(){

System.out.println( "Liczba utworzonych par: " +count);

}}

Słowo kluczowe final

Thinking in Java, Bruce Eckel

… coś co nie moŜe być zmienione…

� Zmienne (prymitywne, obiektowe)� Metody� Klasy

Zmienne finalne

� Określenie, Ŝe zmienna ma być stała� Stałe czasu kompilacji – nigdy nie zmieniane

(wartości znane juŜ w trakcie kompilacji)

� Stałe, którym nadaje wartość tylko raz –inicjowane w czasie działania (konstruktor)

Pole statyczne i finalne

� Zajmuje tylko jeden określony fragment pamięci i nie moŜe ulec zmianie

� static final int A=5;� static final int a= rand.nextInt(20);

Finalne obiekty

� Stała jest referencja a nie obiekt , do którego się odwołuje

� MoŜna zmienić zawartość obiektu, ale referencja nie moŜe pokazywać na inny obiekt

class Value {int i = 1;

}

public class FinalData {//stale czasu kompilacji:final int i1 = 9;static final int VAL_TWO = 99;

public static final int VAL_THREE = 39; // Typowa stała publiczna

final int i4 = (int)(Math.random()*20);static final int i5 = (int)(Math.random()*20);

Value v1 = new Value();final Value v2 = new Value();static final Value v3 = new Value();final int[] a = { 1, 2, 3, 4, 5, 6 };

public void print(String id) {System.out.println( id + ": " + "i4 = " + i4 + ", i5 = " + i5);

}

public static void main (String[] args) {FinalData fd1 = new FinalData();//! fd1.i1++; // Błąd: nie moŜna zmienić wartościfd1.v2.i++; // Obiekt nie jest stały!fd1.v1 = new Value(); // OK -- nie ostatecznyfor(int i = 0; i < fd1.a.length; i++)fd1.a[i]++; // Obiekt nie jest stały!

//! fd1.v2 = new Value(); // Bład: Nie moŜna//! fd1.v3 = new Value(); // zamienić referencji//! fd1.a = new int[3];

fd1.print("fd1");System.out.println("Tworzenie nowego obiektu FinalData");FinalData fd2 = new FinalData();fd1.print("fd1");fd2.print("fd2");

}}

Puste zmienne finalne

� Java pozwala na tworzenie pustych zmiennych finalnych będących polami zadeklarowanymi z modyfikatorem final , ale nie zainicjowanych

� Inicjalizacja przed ich uŜyciem !!! w konstruktorze

� private final Poppet p;

� class Poppet {� private int i;� Poppet (int ii) {i=ii;} }

� public class BlankFinal {� final int i = 0; // Zainicjowana zmienna ostateczne� final int j; // Pusta zmienna ostateczna� final Poppet p; // Puste odwołanie ostateczna

� BlankFinal() {� j = 1; // Inicjalizacja zmiennej ostatecznej� p = new Poppet();� }� BlankFinal(int x) {� j = x; // Inicjalizacja zmiennej ostatecznej� p = new Poppet();� }� public static void main(String[] args) {� BlankFinal bf = new BlankFinal();� }

} ///:~

Finalne argumenty metody

� Wewnątrz metody nie moŜna zmieniać wartości;� public class FinalArguments {� void with(final Gizmo g) {� //! g = new Gizmo (); // Niepoprawne -- g jest

ostateczna

� }� void without(Gizmo g) {� g = new Gizmo (); // OK -- g nie jest ostateczna

� g.spin();� }

Metody finalne

� Blokada metody, zabronienie klasom wydziedziczonym zmian (zapobieganie przesłonięciu)

� Wydajność� wywołanie w miejscu inline� ominięcie normalnej procedury włączenia

kodu ���� kopiowanie rzeczywistego kodu

� Decyduj ący rozmiar kodu metody ����

decyzja po stronie kompilatora Javy

Final i private

� brak dostępu do metod prywatnych – brak moŜliwości ich przesłonięcia – oznacza metodę final

� Przesłonięcie a stworzenie nowej metody

� private final void e() {…}� private void e() {…}

� public final, private final

Klasy finalne

class SmallBrain {}final class Dinosaur {

int i = 7;int j = 1;SmallBrain x = new SmallBrain();void f() {}

}

//! class Further extends Dinosaur {}// błąd: Nie moŜna rozszerzyć ostatecznej klasy 'Dinosaur'

public class Jurassic {public static void main(String[] args) {

Dinosaur n = new Dinosaur();n.f();n.i = 40;n.j++;

}}

�Nie dziedziczymy z tej klasy

Interface

interfejsy

� Klasy abstrakcyjne – udostępniają interfejs, bez definicji

� Forma klasy:� Nazwa metody� Lista argumentów� Typy zwracane

� Zawierają pola: static final (ale nie puste zmienne finalne)

� Metody : public

Przykład – „wielokrotne dziedziczenie” w Javie� interface CanFight {� void fight();� }� interface CanSwim {� void swim();� }� interface CanFly {� void fly();� }

� class ActionCharacter {� public void fight() {}� }

� class Hero extends ActionCharacter� implements CanFight, CanSwim, CanFly {� public void swim() {}� public void fly() {}

}

public class Adventure {static void t(CanFight x) { x.fight(); }static void u(CanSwim x) { x.swim(); }static void v(CanFly x) { x.fly(); }static void w(ActionCharacter x) {

x.fight(); }public static void main(String[] args) {

Hero h = new Hero();t(h); // Traktuje h jako CanFightu(h); // Traktuje h jako CanSwimv(h); // Traktuje h jako CanFlyw(h); // Traktuje h jako

ActionCharacter}} ///:~

Dziedziczenie interfejsów

� interface Monster {� void menace();� }

� interface DangerousMonsterextends Monster {

� void destroy();� }

� interface Lethal {� void kill();� }

� class DragonZillaimplements DangerousMonster {

� public void menace() {}� public void destroy() {}� }

interface Vampireextends DangerousMonster,

Lethal {void drinkBlood();

}

public class HorrorShow {static void u(Monster b) {

b.menace(); }static void v(DangerousMonster d) {

d.menace();d.destroy();

}public static void main(String[] args)

{DragonZilla if2 = new

DragonZilla();u(if2);v(if2);

}}

Interfejsy – grupowanie stałych „enum”

� Dane są styczne i finalne

� public interface Months {� int� JANUARY = 1, FEBRUARY = 2, MARCH = 3, � APRIL = 4, MAY = 5, JUNE = 6, JULY = 7, � AUGUST = 8, SEPTEMBER = 9, OCTOBER =

10,� NOVEMBER = 11, DECEMBER = 12;� }

Typy danych

Typy proste

wartości logiczne: prawda lub fałsz

true false1boolean

znaki Unicodu-0...655562char

-1.xE+308...1.xE3088double

liczby rzeczywiste-3.xE+38...3.xE+384float

-9223372036854775808 ...9223372036854775807

8long

-2147483648...21474836474int

-32768...327672short

liczby całkowite-128...127lbyte

Znaczenieprzedziały wartościLiczbabajtów

Nazwa typu

Deklaracje

Deklaracje typów prostych deklaracja jest zarazem definicją - wydziela w pamięci miejsce na przechowanie zmiennej danego typu.

Deklaracja zmiennej typu obiektowego jest faktycznie deklaracją (i definicją) referencji do obiektu, nie wydziela natomiast w pamięci miejsca na przechowanie samego obiektu.

String s ;s = "ala ma kota";

int a = l;String s = "ala ma kota";

Konwersje arytmetyczne

� byte, short, char � int� float � double� long � double.

� int ii; short ss; � ss = 1;� ii = ss; � ss = ii; ���� błąd� ss = (short)ii; � OK.;

Operatory i wyraŜenia

Odejmowanie-

Dodawanie+3, lewe

Reszta z dzielenia%

Dzielenie/

MnoŜenie*

2, lewe

Konwersja (rzutowanie)(typ)

Operator zmniejszania--

Operator zwiększania++

Jednoargumentowy - (liczba ujemna)-

Jednoargumentowy + (liczba dodatnia)+

Bitowe uzupełnienie do l~

Negacja logiczna!1, praweNazwaOperatorPriorytet, Wi ązanie

Operatory i wyraŜenia

Nierówności!=

Operatory równości -==

6, lewe

Stwierdzenie typuinstanceof

Operatory relacyjne< <= >= >

5, lewe

Przesunięcie bitowe w prawo bezznaku

>>>

Przesunięcie bitowe w prawo>>

Przesunięcie bitowe<<

4, lewe

NazwaOperatorPriorytet, Wiązanie

Operatory i wyraŜenia

Operatory przypisania%= += &= |= <<=13, prawe

Operator warunku?:12, prawe

Logiczna alternatywa||11,

Logiczna koniunkcja&&10,

Bitowa alternatywa|9,

Bitowe wyłączające ALBO^8.

Bitowa koniunkcja&7,

NazwaOperatorPriorytet, Wi ązanie

Operatoryx = a > b; //x � boolean!!!x = a > b && c<d;

String s1;String s2 = "Napis";s1 = s2 + " tralala"; s1 = s1 + s2;

int k = 1;s1 = k + k + s2; // 2Napis s1 = s2 + k + k; // Napis11 s1 = s2 + (k+k); // Napis2 s1 = k + k; // błąd kompilacji (jeden z argumentów musi być typuString)

Operatory

Do porównywania obiektów nie naleŜy uŜywać operatorówrelacyjnych i równości – nierówności!

String s2 = "Napis";String s3 = new String("Napis");

boolean b;b = (s2 == s3); // porównanie referencji: wynik false b = s2.equals(s3); // wynik true.

Instrukcje sterujące

return wyr;

break [etykieta];

continue [etykieta];

for (wyr1; wyr2; wyr3)ins

do ins while (wyr);

while (wyr) ins;

switch (wyr){case ws1 : ins1 . . . . case wsN:ins3 default : insDef}

if (wyr) ins1else ins2

if (wyr) ins

wyraŜenie wyr musi być wyraŜeniem całkowitym.

Instrukcja break

int i = 0;int j = 0;outerloop: // etykietawhile (i < 100){

i++;while ( true ){

j++;. . . . . .

if (i + j > 10) break outerloop;// przerwanie p ętli oznaczonej etykiet ą outerloop, a nie bie Ŝącej

}}

Zasięg zmiennych

Uwaga: W Javie instrukcje wyraŜeniowe i sterujące moŜna umieszczać wyłącznie w metodach klasy lub w bloku statycznymZasięg identyfikatora - fragment programu, w którym moŜe być uŜywany. Zasięg składowych klasy – w kaŜdym miejscu klasy (miejsce deklaracji nieistotne)Zasięg identyfikatorów definiowanych wewnątrz metody jest lokalny. Zasięg parametrówmetody jest lokalny

W metodzie metoda1() moŜemyodwoływać się do zmiennej a, zmiennej b oraz metodymetoda2(), a w metodziemetoda2() moŜemy odwoływaćsię do zmiennej a, zmiennej c i metody metoda1.

class A {int a;void metoda1(){

int b;}void metoda2() {

int c;}

}

Przesłanianie nazw zmiennych

NIE W Javie nie wolno przesłaniać zmiennych lokalnych w blokachwewnętrznych:

int a;{

int a; // B ŁĄD kompilacji}

TAK W konstruktorach i metodach moŜemy przesłaniać identyfikatory pólklasy:class A {

int a;void metoda(){

int a = 0; // przes łoni ęciea = a + 10; // zmienna lokalna;this .a++; // pole klasy

}

Czas Ŝycia zmiennych

Zmienne lokalne i referencje - od momentu deklaracji do wyjścia sterowaniaz blokuObiekty – od chwili wykonania operacji new – do chwili usunnięcia przezgarbage collector

class A {String s ;void metoda1() {

String pies = new String( "Pies" );s = pies;} void metoda2(){

System.out.println( "Jest " + s);}

}

Obiekt „pies" został stworzonyw metodzie1.Referencja pies po zakończeniudziałania tej metody przestajeistnieć. PoniewaŜ jednakreferencja s wskazuje na obiekt„pies”, to obiekt nadal istnieje. MoŜemy się do niego odwołaćw metodzie2.

Specyfikatory dostępu

dostępna zewsządpublicpubliczny

dostępna z danej klasy i wszystkichklas ją dziedziczących

protectedchroniony

dostępna ze wszystkich klasdanego pakietu

- (ew package)zaprzyjaźniony / pakietowy

dostępna tylko w danej klasieprivateprywatny

Opisspecyfikator dostępupola/metody

Dostęp do pól i metod klasy

Inicjalizacja pól

Przy tworzeniu obiektu pola klasy mają zagwarantowanąinicjalizację na wartości ZERO (0, false - dla typu boolean, null - dla typów obiektowych, nie dotyczy to lokalnych zmiennych.

PRZYKŁAD JAWNEJ INICJALIZACJIclass Para {

static String text = "Pary" ; static int x = -1;int a = x+1; int b = x+1; Para() { a++; b++; }static String getText() { return text; } void show(){

System.out.println( "( " + a + "," + b + ")" );}

}

Kolejność inicjalizacji pól

REGUŁY DOTYCZĄCE KOLEJNOŚCI:•kaŜde odwołanie do klasy inicjalizuje najpierw pola statyczne•tworzenie obiektu (new) inicjalizuje pola niestatyczne, po czym wykonywany jest konstruktor•kolejność inicjalizacji pól - według ich kolejności w definicji klasy (w podziale na statyczne i niestatyczne, najpierw statyczne)

NIE (błąd: forward reference)class Para {

static int y = x + 1;int a = x+1;int b = x+1;static int x = - 1;

}

TAKclass Para{

static String text = "Pary";int a = x+1 ;int b = x+1;Para() { ... } Para(int x){ ... } Para(int x, int y) { ... }static int x = -1;

}

Typ tablicowyDeklaracja tablicytworzy referencję.Taka deklaracja nie alokuje pamięci dla samej tablicy.

int[] arr; // arr jest referencją MoŜna pisać teŜ int arr[];// arr jest zmienną typu int[], który jest typem obiektowym

Alokowanie pamięci. Rozmiar tablicy moŜe być ustalanydynamicznie podczas działania programu

arr = new int[l0];int[] tab = new int[n];

Tablice - przykłady

public static void main(String[] args){

for ( int i = 0; i < args.length; i++)System.out.println(args[i]);

}

Przykład:Przetwarzanie wszystkich elementów tablicy

Przykład:Przekroczenie zakresu tablicy– kontrolowanie ilości parametrów programu

public static void main(String[] args){

try {

System.out.println(args[0] + " " + args[1]);}

catch ( IndexOutOfBoundsException e){

System.out.println( "Syntax: ... " );

System.exit(1);}

}

Tablice - przykłady

Inicjalizatory klamrowe

Button[] tab = new Button[n];

for ( int i = 0; 1 < tab.length; i++)

tab[i] = new Button( "Przycisk " + i);

Tablice elementów obiektowych – wymaga inicjalizacji wszystkich obiektów - elementów

int a[] ={1, 2, 3, 4, 5, 3}; //ale tylko w wierszu deklaracji tablicy

Button b[] ={ new Button( "A" ), new Button( "B" ) , new Button( "C" ) ,

/* tu przecinek dozwolony*/ };

Tablice - w przypisaniach byte [] b1 = {l, 2, 3 };

byte [] b2 = {l, 2, 3, 5, 5 };

b2 = b1;

Tablice - przykłady

Component[] tab= new Component[]{ new Button( "A" ),

new Button( "B" ), new Label( "A" ), new Label( "B" ),};

for ( int i=0;i<tab.length;i++)

tab[i].setBackground(Color.blue);

Tablice róŜnych obiektów (takie tablice takŜe jako argument funkcji)

void chgtab( byte [] t){

for ( int i=0; i < t.length; i++) t[i]++;

}

byte [] b1 = {1, 2, 3 };

chgtab(b1);

Tablice jako argumenty metod

Tablice wielowymiarowePrzykładowe sposoby deklaracji i inicjalizacji:

1. inicjalizacja w nawiasach klamrowych

int[][] macierz2 = new int[n][m];

int[][] macierz1 = {{ l, 2, 3 }, { 4, 5, 6}};

2. dynamicznie

Tablice wielowymiarowePrzykładowe sposoby deklaracji i inicjalizacji:

3. tablica składa się z wektorów o róŜnych rozmiarach

public static void main(String[] arg){

int w[] = { 2, 3, 4 }; int n = 3;int [][] m3 = new int [n][]; // rozmiary wierszy b ędą zm. Dynam.for ( int i = 0; i < m3.length; i++){

m3[i] = new int [w[1]];for ( int j = 0; j < m3[i].length; j++)

m3[i][j] = i + j;}for ( int i = 0; i < m3.length; i++) {

System.out.println( "Rozmiar i-go wiersza " + m3[i].length);String out = " " ;for ( int j = 0; j < m3[i].length; j++)

out += " " + m3[i][j]; System.out.println(out);

}}

78

Tablice kopiowanie

int[] a;int[] b = {5, 6, 7, 8, 9};a = b; // WRONG ! Kopiowania tylko referencja

Correct :a = new int[b.length];for(int i=0; i < b.length; i++) a[i] = b[i];

Metoda do kopiowania java.lang.System.arraycopy(sourceArray, src_pos, destArray, dest_pos, length);

Przykład System.arraycopy(b, 0, a, 0, b.length);

MoŜliwe Exceptions : NullPointerException (if sourceArray or destArray null), IndexOutOfBoundsException (e.g. src_pos negative), or ArrayStoreException

(element type mismatch).

79

Tablice

Zwrot tablic przez metody

przykład ( [Barteczko’04, vol. 1, p. 191])

int[] dblVal(int[] tab) {int[] output_arr = new int[tab.length];for(int i=0; i<output_arr.length; i++)

output_arr[i] = tab[i] * 2;return output_arr;

}

80

Tablice

public static void main(String[] arg){

int [] w = { 2, 3, 4 }; int n = 3;int [][] m3 = new int [n][]; // row sizes - dynamicfor ( int i = 0; i < m3.length; i++){

m3[i] = new int [w[i]];for ( int j = 0; j < m3[i].length; j++)

m3[i][j] = i + j;}for ( int i = 0; i < m3.length; i++) {

System.out.println( "i-th row size: " + m3[i].length);String out = " " ;for ( int j = 0; j < m3[i].length; j++)

out += " " + m3[i][j]; System.out.println(out);

}}

81

double b = 1 / 3; // ?

jak w C/C++: dzielenie całkowite, wynik: 0.

zastosuj 1.0 / 3.0.

Konwersja danych

A co teraz?int c = 1.0 / 3.0;//error

Java musi być pewna, Ŝe chcesz stracić pewną część informacji

int c = (int)(1.0 / 3.0);//OK

82

Typy konwersji (arithmetic)

int i;

short sh;

sh = 5; // OK; 5 is int but is constant and// is small enough (no information loss)

i = sh; // expanding, ok

sh = (short)i; // OK – with the explicit cast

int2int

double d = 5.12;

i = d; // WRONG! Conversion must be explicit

// but:i = (int)d; // OK. The fraction is cut off

float2int

83

Błędny zapis??float width = 5.5; // error

Compiler message:zmniejszenie precyzji

found: doublerequired: float

OKfloat width = (float)5.5; //

float width = 5.5F; // or ...5.5f

84

Łańcuchy znaków

String s1 = "abc";String s2 = "ab";

s2 += "c";boolean result = (s1==s2); // true?

False. RóŜne objekty � róŜne referencje. Zawartośćnieistotna

Jak porównać?if (s1.equals(s2)) ... lub

if (s1.equalsIgnoreCase(s2)) ...

String s1 = "abc"; String s2; s2 = s1; // kopiowanie poprawne?

Lepiej: s2 = new String(s1);

85

Powiązanie łańcuchów znaków i liczb

String s1 = "Johnny has drunk ";int count1 = 2, count2 = 1;

String s2 = " beers.";String s3 = s1 + count1 + s2;

String s4 = s1 + (count1 + count2) + s2;String s5 = s1 + count1 + count2 + s2;

String s6 = count1 + count2 + s2;

86

Przeładowanie metod

• int Fun(int x)• int Fun(float y)• int Fun(int a, float b)

Wszystkie w jednej klasie

Error!!• int Fun(int x)

and• boolean Fun(int y)

PrzeciąŜanie metod

p.add(jakasPara);p.add(3); p.add(1,2);

void add(Para p) { a += p.a; b += p.b;} void add( int i) { a += i; b += i; }void add( int i, int k){a += i; b += k; }

PrzeciąŜenie konstruktorów

Para( int x) { a = x; b = x; }

// oba pola inicjalizowane t ą samą liczb ąPara( int x, int y)

{

// ka Ŝde pole inicja1izowane inn ą liczb ąa = x;

b = y;}Para() { this (1); }

Para( int x) { this (x,x);} Para( int x, int y){

a = x;b = y;

}

Dziedziczenie

1. wywoływany jest konstruktor klasy pochodnej2. jeśli pierwszą instrukcją jest super(args), wykonywany jest konstruktor klasy

bazowej z argumentami args,3. jeśli nie ma super(...), wykonywany jest konstruktor bezparametrowy klasy

bazowej,4. wykonywane są instrukcje wywołanego konstruktora klasy pochodnej.

Sekwencja budowania obiektu klasy pochodnej

•dziedziczenie pozwala wykorzystywać istniejący interfejs na rzecz obiektu klasypochodnej, kompozycja - nie,

•dziedziczenie oznacza, Ŝe obiekt klasy pochodnej moŜe być traktowany tak samo jakobiekt typu definiowanego przez nadklasę.

Podstawowe róŜnice między kompozycją a dziedziczeniem:

Uwaga: Java nie uwzględnia wielodziedziczenia

Obiektowe konwersje rozszerzające

KaŜdy obiekt moŜemy przekształcić w obiekt jego (dowolnej) nadklasy.

Nazywa się to konwersją rozszerzającą alboupcasting, (up - bo w górę hierarchiidziedziczenia).

Obiektowe konwersje rozszerzające dokonywane są automatycznie (nie musimystosować operatora konwersji) przy:

• przypisywaniu zmiennej-referencji odniesienia do obiektu klasy pochodnej,

• przekazywaniu argumentów, gdy parametr jest typu nadklasy argumentu,

• zwrocie wyniku, gdy wynik podstawiamy na zmienną oznaczającą obiekt nadklasyzwracanego wyniku.

Obiektowe konwersje rozszerzające

static Para sum(Para pl, Para p2, Para p3){

Para p = new Para(0,0);p.add(pl);p.add(p2);p.add(p3);return p;

}

Para p1 = new Para(1,2); ParaInh pi1 = new ParaInh(3,4),

pi2 = new ParaInh(5,6);

Para wynik = sum(pp1, pi1, pi2);

Zastosowanie polimorfizmuclass Zwierz {

String name = "nieznany" ;Zwierz() {}Zwierz(String s) {name = s; }String getTyp() { return "Jaki ś zwierz" ;}String getName() { return name;}String getVoice(){ return "?" ;}void speak() {

System.out.println(getTyp()+ " " +getName()+ " mówi "

+getVoice());}

}

class Pies extends Zwierz {Pies(){}Pies(String s){ super (s); }String getTyp(){ return "Pies" ; }String getVoice(){ return "HAU, HAU!" ; }

}

class Kot extends Zwierz {Kot() {} Kot(String s) { super (s); }String getTyp() { return "Kot" ; }String getVoice(){ return "Miauuuu..." ; }

}

Zastosowanie polimorfizmuclass Main {

public static void main(String[] arg) {Zwierz z1 = new Zwierz(), z2 = new Zwierz();Pies pies = new Pies(), kuba = new Pies( "Kuba" );Pies reksio = new Pies( "Reksio" );Kot kot = new Kot();Dialog(z1, z2);Dialog(kuba, reksio);Dialog(kuba, kot);Dialog(reksio, pies);

}static void Dialog(Zwierz z1, Zwierz z2){

z1.speak();z2.speak();System.out.println( "---------------" );

}}

Wynikiem działania programu będzie następujący wydrukJaki ś zwierz nieznany mówi ? Jaki ś zwierz nieznany mówi ?Pies Kuba mówi HAU, HAU! Pies Reksio mówi HAU, HAU!Pies Kuba mówi HAU, HAU! Kot nieznany mówi Miauuuu. ..Pies Reksio mówi HAU, HAU! Pies nieznany mówi HAU, H AU!

Metody wirtualne

Wszystkie metody w Javie są wirtualne

Dynamic binding (Late binding) – mechanizm pozwalający wykryćna jaki obiekt wskazuje referencja i zastosować odpowiedniąmetodę.

za wyjątkiem:

•metod statycznych,

•metod deklarowanych ze specyfikatoremfinal,

•metod prywatnych (dla którychodwołania w innych metodach danej klasynie są polimorficzne).

Metody i klasy abstrakcyjne

Metoda abstrakcyjna nie ma implementacji (ciała) i winna być zadeklarowana ze specyfikatorem abstract.

Klasa, w której zadeklarowano jakąkolwiek metodę abstrakcyjną jest klasąabstrakcyjną i musi być opatrzona kwalifikatorem abstract.

abstract class SomeClass {int n;abstract int getSomething();void say(){

System.out.println( "Coś tam" );}

}

Abstrakcyjność klasy oznacza, iŜ nie moŜna bezpośrednio, np. w wyraŜeniu newtworzyć jej egzemplarzy.

Standardowe klasy Javy

� java.applet, java.awt, java.beans, java.io, java.lang, java.math, java.net, java.rmi, java.security, java.sql, java.text, java.util, javax.accessibility, javax.swing, org.omg.

Pakiety

� java.util.Date data = new java.util.Date();

� import java.util.*;

java.lang

� W pakiecie java.lang zdefiniowana jest klasa Object, która jest klasą nadrzędną wobec wszystkich innych klas Javy.

� Boolean, Byte, Integer, Long, Double, Character itd.,

� Klasa Math� Klasa Thread

java.lang

� 2 klasy obsługujące łańcuchy znaków: String i StringBuffer .

� Klasa String uŜywana jest do przechowywania i wykonywania operacji na stałych ła ńcuchach ; po utworzeniu obiektu tej klasy nie moŜna zmienić jego wartości.

� Klasa ta zawiera metody:� do sprawdzania poszczególnych znaków, porównywania łańcuchów,

wyodrębniania podłańcuchów, tworzenia kopii z zamianą na małe albo duŜe litery.

� Klasa StringBuffer implementuje łańcuchy znaków, które mogą byćzmieniane . Podstawowe metody tej klasy to append dodająca znaki na końcu bufora i insert wstawiająca znaki w określonym miejscu.

� KaŜdy obiekt przydziela bufor na przechowywany łańcuch znaków. JeŜeli całkowita długość łańcucha wzrośnie powyŜej rozmiaru bufora, automatycznie przydzielany jest większy.

Pakiet java.io

� definiuje klasy implementujące operacje wejścia-wyjścia.

� Reader wraz z podklasami:� BufferedReader, � CharArrayReader, � InputStreamReader, � FileReader, � StringReader

� Writer wraz z podklasami:� BufferedWriter, � CharArrayWriter, � OutputStreamWriter, � FileWriter,� PrintWriter,

import java.io.*;import java.util.*;

public class czytam {public static void main (String args[]){

EasyIn easy = new EasyIn();System.out.print("enter float: "); System.out.flush();System.out.println("You entered: " + easy.readFloat() );float a=easy.readFloat();System.out.println("You entered: " + a);}

}

class EasyIn

{static InputStreamReader is = new InputStreamReader( System.in );static BufferedReader br = new BufferedReader( is );StringTokenizer st;StringTokenizer getToken() throws IOException {

String s = br.readLine();return new StringTokenizer(s);

}float readFloat() {

try {st = getToken();return new Float(st.nextToken()).floatValue();

} catch (IOException ioe) {System.err.println("IO Exception in EasyIn.readFloat");return 0.0F;

}}

}

pakiet java.util

� szereg klas definiujących róŜne struktury danych przechowujące inne obiekty.

� Klasa Vector implementuje tablicę obiektów, która moŜe rosnąć lub zmniejszać się w miarę jak obiekty są dodawane lub usuwane.

� Wszystkie elementy wektora najwygodniej jest przeglądać wykorzystując interfejs Enumeration

� Gdy wektor zajmuje całą przydzieloną pamięć, przed dodaniem kolejnego elementu jego rozmiar jest automatycznie zwiększany o wartość capacityIncrement .

� Program moŜe jednak sam zwiększyć rozmiar wektora przed wstawieniem duŜej porcji danych, aby uniknąć wielu realokacji .

� Podklasą klasy Vector jest Stack realizujący kolejkę LIFO obiektów z metodami push i pop .

java.util.zip

� W pakiecie java.util.zip znajdują się klasy pozwalające tworzyć i czytać pliki skompresowane w formatach ZIP i GZIP.

Pakiet java.net

� Pakiet java.net zawiera klasy realizujące połączenia sieciowe zarówno na poziomie gniazd, jak i adresów URL wskazujących zasoby w WWW. Podstawowe klasy to:� Socket, URL, URLConection.

Pakiet java.sql

Jednolity standard dostępu do dowolnych relacyjnych baz danych. Klasy z tego pakietu implementują połączenia z bazą danych, zapytania SQL, wyniki tych zapytań itp.

Driver JDBC (Java DataBase Conectivity)

java.rmi� RMI (Remote Method Invocation ) zawarty w java.rmi umoŜliwia tworzenie

rozproszonych aplikacji w Javie.� RMI zapewnia mechanizm, poprzez który odbywa się komunikacja pomiędzy

serwerem i klientem oraz przesyłane są dane w obie strony.

org.omgWspiera powszechnie przyjęty standard modelu rozproszonych obiektów – CORBA (Common Object Request BrokerageArchitecture). Pozwala on na komunikację pomiędzy obiektami bez względu na platformę systemu operacyjnego, ani uŜyty języka programowania.

pakiet java.awt� Aplety i aplikacje Javy komunikują się z uŜytkownikiem wykorzystując klasy z

pakietu java.awt składające się na graficzny interfejs uŜytkownika AWT(Abstract Window Toolkit).

� AWT dostarcza typowe komponenty graficzne takie, jak klawisze, pola do wprowadzania tekstu, listy wyboru itd. poprzez klasy:

� Button, � Checkbox, � Choice, � Label, � List, � Menu, � Scrollbar,� TextArea, � TextField będące pochodnymi klasy Component.

� Wykorzystując klasę Canvas , moŜna rysować dowolne obrazy graficzne na ekranie;

� Po dodaniu odpowiedniej obsługi zdarzeń moŜna zdefiniować dowolny własny komponent .

Wyjątki

W języku Java istnieje bardzo rozbudowana hierarchia (drzewo) predefiniowanych klas wyjątków,których superklas ą jest klasa Throwable , a głównymi gałęziami drzewa są klasy Error i Exception .

Wyjątki pozwalają zachować kontrolę nad przebiegiem wykonania funkcji (metod), a takŜe pojedynczych instrukcji zawartych w funkcjach. Wyjątek jest zdarzeniem, które pojawia się podczas wykonania i rozrywa normalnąkolejność wykonania instrukcji.

- Wyjątki weryfikowalne

- Wyjątki nieweryfikowalne

Wyjątki - throw

�Dla obsługi wyjątków weryfikowalnych wprowadzono cztery słowa kluczowe: throw , throws , try , catch i finally .

� Słowo kluczowe throwthrow słuŜy do jawnego zgłaszania wyjątków nieweryfikowalnych i występuje w instrukcji throw(throw wyra Ŝenie ; typu referencyjnego do klasy Throwable lub jej podklas).

� Zgłoszenie wyjątku w instrukcji throwthrow spowoduje natychmiastowe opuszczenie bloku zawierającego instrukcję throw i znalezienie instrukcji trytry , której fraza catchcatch przechwyci zgłoszony wyjątek.

� JeŜeli nie ma takiej instrukcji try, zostanie wywołana metoda UncaughtException i wykonanie programu (lub wątku) zostanie zakończone.

Fraza:throws klasa_wyjątków

� public staic void main(String args[]) throwsException {/*...*/}

� void printNumber(int number) throwsWrongNumberException {/*...*/}

try … catch…

� JeŜeli wykonanie pewnej instrukcji programu moŜe spowodowaćpowstanie wyjątkowego zdarzenia, to musi ona być ujęta w blok instrukcji try , po którym muszą wystąpić procedury obsługi wyjątku mające postać frazy catch i bezpośrednio po catch(opcjonalnie) frazy finally .

� try {I}� catch(arg1 e1) {I} � catch(arg2 e2) {I} � ... � catch(argn en) {I} � ... � finally {I}

Sterowanie przekazywane jest dopierwszej w kolejno ści klauzulicatch, której „argument" (typwyjątku) pasuje do typupowstałego wyjątku

najpierw podawać BARDZIEJ SZCZEGÓŁOWE TYPY WYJĄTKÓW!!!

Klauzula finally

Był wyjątek?

przerwij try uruchomjest klauzulę catch.

wykonaj klauzulęfinally

wykonaj klauzulęfinally

Przejdź do następnejlinii programu

TAK

NIE

boolean metoda(...){

try{

/*instrukcje,które mog ą

spowodować wyj ątek*/}catch (Exception e){

return false ; } finally{

/* uporz ądkowanie, np. zamkni ęcie pliku*/

} return true ;

}

Schemat obsługi wyjątków

int a, b, c; String s;try {// wyj ątek ArithmeticException

s = Integer.toString(a);}

catch (ArithmeticException ex) {// wyj ątek jest obsługiwany w bloku catch

s = "*" ;}

Własne wyjątki

Wyjątki są obiektami klas pochodnych od Throwable.

Aby stworzyć własny wyjątek, naleŜy zdefiniować odpowiednią klasę.

Zgodnie z konwencją dziedziczymy podklasę Throwable - klasęException .

class NaszWyj extends Exception{. . . . . .

void naszaMetoda() throws NaszWyj{

. . . . .if (bł ąd)throw new

NaszWyj(ew_param_konstruktora_z_info_o_bł ędzie);}

}