Upload
phungtu
View
212
Download
0
Embed Size (px)
Citation preview
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.
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
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
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);
}}
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
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 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.
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);}
}