Java programozás alapjai
A Java nyelv
C++ szintaktikára épít, számos különbséggel Hello, World (alkalmazás, parancssorból indítható):
A HelloWorldApp.java fájl: A főosztály: neve = fájlnév, van benne main
A program belépési pontja: statikus metódus
class HelloWorldApp { public static void main(String[] args) { System.out.println("Hello World!"); } }
cout
<< …
<< ‘\n’ 2 / 59
Hello world futtatása HelloWorldApp.java javac HelloWorldApp.java HelloWorldApp.class
class HelloWorldApp { public static void main(String[] args) { System.out.println("Hello World!"); } }
Szimbólumtábla: main: public, static, void … ...
java HelloWorldApp Belölti a HelloWorldApp.class fájlt és elindítja a main függvényt. Mivel még nincs ilyen objektum a main szükségképpen statikus 3 / 59
Java adattípusok Egyszerű adattípusok (int, float) Osztályokkal objektumok Nincs külön mutató, referencia, címe operátor, • helyette: objektumok csak dinamikusan hozhatok létre és csak referenciával hivatkozhatunk rájuk Egyszerű adattípusoknak van csomagoló objektuma Tömbök (is objektumok) Sztringek
4 / 59
Egyszerű adattípusok Egyszerű alaptípusok: byte short int long float double char boolean
8-bites előjeles egész 16-bites előjeles egész 32-bites előjeles egész 64-bites előjeles egész 32-bites lebegőpontos (IEEE 754) 64-bites lebegőpontos (IEEE 754) 16-bites Unicode karakter Bool-érték (igaz v. hamis)
Az egész típusok szélessége nem függ a platformtól Előjel nélküli (unsigned) egész nincs! Az == operátor alkalmatlan két double egyenlőségének vizsgálatára! 5 / 59
“Unsigned” egészek
byte unsigned értékének kiolvasása:
byte b; int i = b & 0xff;
32-bites int unsigned értékének kiolvasása:
int i; long l = i & 0xffffffffL;
6 / 59
Implicit típuskonverzió
Implicit konverziót csak bővítésnél (widening primitive conversion) lehet használni : byte -> short -> int -> long -> float -> double char -> int -> long -> float -> double
Egész típusok bővítő konverziója esetén az eredeti pontos értéket megőrizzük
A byte -> char, illetve short -> char konverziók nem tekinthetőek bővítésnek, mivel a char unsigned: byte b = 126; short s = 1000; char c; c = b; // compile error: possible loss of precision c = s; // compile error: possible loss of precision
Az int -> float, long -> float, long -> double konverziók csökkenthetik a számábrázolás precizitását, ilyenkor az eredeti egész értékeket kerekítjük
7 / 59
Explicit típuskonverzió
Szűkítésnél (narrowing primitive conversion) kötelező explicit konverziót (cast operatort) használni: double -> float -> long -> int > char -> short > byte
pl.: int i = 32; byte b = (byte)i;
Szűkítés esetén az alsó biteket őrizzük meg, így előfordulhat, hogy az eredeti érték nagyságrendjét is elveszítjük 8 / 59
Explicit típuskonverzió
Példák implicit/explicit konverzióra • int a = 1; // a == 1 • float a = (float)1; // a == 1.0 • float a = 1/2; // a == 0.0 • float a = (float)1/2; // a == 0.5 • int a = 3.14; // a == 3
9 / 59
Típuskonverzió függvényekkel
Primitív és összetett típusok között nincs implicit/explicit konverzió • int → String • String egy = Integer.toString(1); • String egy = “” + 1; • String → int • int a = Integer.parseInt(“1”);
10 / 59
Egyszerű adattípusok specialitásai Változó létrehozása default (zérus) kezdőértékkel: int i; Változó létrehozása kezdőértékkel: int i = 5; Egyszerű adattípusok deklarációja és definíciója (memória foglalás) egyszerre történik Konstans változó a final kulcsszóval (C++ const): final double pi = 3.14159286; 11 / 59
Osztályok Minden adatstruktúra osztály (class) típusú nincs struct, union Az osztály más csomagból is
Változókhoz kezdőértéket rendelhetünk vagy alapért.
public class Employee { String name; csomagból private long salary = 100;
A törzs csak az osztályon belül lehet
osztályból public Employee(String n, long sal) { name = n; salary = sal; } }
bárhonnan
Nem kell a végén pontosvessző
12 / 59
Osztályok
objektumok prototípusa
összefüggő adatok és metódusok gyűjteménye • pl. String objektum: karakterek tömbje és a rajtuk végezhető műveletek
13 / 59
Osztály példány = objektum
példányt mindig a new operátorral hozunk létre nem lehet objektumot lokális változóként létrehozni a változónk mindig hivatkozást tartalmaz Student s1; // deklaráció s1 = new Student(“Ubul”, 3.5);// definíció
az = a hivatkozást másolja, az objektumot NEM! Student s2 = s1; // s2 ugyanaz az objektum // lesz, mint s1! 14 / 59
Minden objektum dinamikus C++
Java
class Vector { int x, y; }; ….
class Vector { int x, y; } ….
Vector v; // stack-en Vector *pvnull = NULL; Vector *pv = &v; Vector& rv = v; Vector *pvd = new Vector(); delete pvd;
Vector Vector Vector Vector Vector
v = new Vector( ); pvnull; pv = v; rv = v; pvd = new Vector();
szemétgyűjtés
15 / 59
Érték versus Referencia típusok: C++ Globális memóriában vagy a vermen Deklaráció és helyfoglalás egyszerre Sohasem null = adatot másol nem referenciát
Dinamikus memóriából allokált Deklaráció és helyfoglalás külön Lehet null “=” referenciát másol nem adatot
A tömbjeiben elemek vannak Akárcsak a beépített típusok
A tömbjeiben referenciák vannak Nem úgy viselkedik, mint a beépített típusok
int i, j=3;
Class c; c.f( );
i = j; Class c1 = c;
int * pi; ... pi = new int; *pi = 3;
Class* c;
int * pj = pi;
Class* c1 = c;
c = new Class; c->f( );
int array[10]; 16 / 59
Érték versus Referencia típusok: Java Globális memóriában vagy a vermen Sohasem null = adatot másol nem referenciát A tömbjeiben elemek vannak
Dinamikus memóriából allokált Lehet null = referenciát másol nem adatot A tömbjeiben referenciák vannak
BEÉPÍTETT TÍPUSOK
OBJEKTUMOK
int i, j=3;
int * pi; ... pi = new int; *pi = 3;
Class c;
int * pj = pi;
Class c1 = c;
Class c; c.f( );
i = j; Class c1 = c;
c = new Class; c.f( );
int array[10]; int array[]; array = new int[10];
17 / 59
Visszatérés objektummal C++
Java
class Vector { … Vector Add(const Vector& v) { return Vector(x + v.x, y + v.y); } … };
class Vector { … public Vector Add(Vector v) { return new Vector(x + v.x, y + v.y); } … }
18 / 59
Egyszerű adattípusok osztályba csomagolása Minden egyszerű adattípusnak létezik egy osztály típusú megfelelője, pl. int és Integer konverziós függvények típusra jellemző konstansok int i1 = 5; Integer io = new Integer(i1); Integer ios = new Integer(“135”); int i2 = io.intValue(); float f = io.floatValue(); String s = io.toString(); i1 = Integer.MAX_VALUE;
19 / 59
Példa: generikus tár C++
Java
1. Template 2. void pointer 3. Alaposztályra mutató pointer vagy referencia
nincs (1.5.0 Generics) nincs pointer Mi az alaposztály: Object !!! class Tar { Object obj; void Put(Object o) { obj = o; } Object Get() { return obj; } } …. Tar tar = new Tar(); tar.Put( 3 ); tar.Put( new Integer(3) );
☺ 20 / 59
Tömbök
értékek indexelt listája bármilyen típusból létrehozhatunk tömböt a [ ] operátorral • int[] tomb; // üres tömb • int tomb[]; // üres tömb a tömb minden eleme azonos típusú
21 / 59
Tömbök
a tömb is objektumként viselkedik • new-val kell inicializálni • int tomb[] = new int[1]; • létrehozáskor is inicializálhatjuk • int tomb[] = { 1, 2, 300000 };
22 / 59
Tömbök
mérete konstans a length attribútum tartalmazza a hosszát • int meret = tomb.length; • az elemek a [ ] operátorral érhetőek el a 0.. length -1 tartományban
23 / 59
Tömb elemek bejárása
while
int tomb[] = new int[10]; int i = 0; while(i < tomb.length){ tomb[++i] = i*i; }
24 / 59
Tömb elemek bejárása
for
int tomb[] = new int[10]; for( int i = 0; i < tomb.length; ++i ){ tomb[i] = i * i; }
25 / 59
Tömb elemek bejárása
for each
int tomb[] = { 1, 3, 2, 5, 4 }; for( int i : tomb ){ System.out.println(i); }
26 / 59
Tömbök int[] intArray = new int[5]; // vagy int intArray[] = new int[5]; int i = intArray[2]; int l = intArray.length;
deklaráció és inicializálás egy lépésben: int[] intArray = { 1, 3, 2, 4, 7 }; korábban deklarált tömb átdefiniálása: intArray = new int[] { 3, 2, 4, 8, 7, 5 };
27 / 59
Sztringek String osztály: Tartalma a létrehozás után nem módosítható, Idézőjelek közé tett szövegből mindig String lesz, pl. String s = “abc”; System.out.println(“Hello”);
Példák: String s = “abc”; int i = s.compareTo(“cde”); System.out.println(String.valueOf(i) + s.subString(1,2) + “ef”); int l = s.length();
28 / 59
Operátorok A legtöbb művelet a C++-hoz hasonlóan működik + - * / % >> << && || ! & | ^ > >= < <= == != ?: () (típus) new Leglényegesebb különbségek: nincs operator overloading nincs -> operátor: mindig pontot használunk nincs :: operátor (aminek a bal oldalán nem példány, hanem osztály áll): ehelyett is pontot használunk instanceof operátor: igaz, ha az A objektum a B osztály vagy B-ből származó osztály tagja 29 / 59 if (A instanceof B) { ... }
Vezérlőszerkezetek A legtöbb a C++-ban megszokott módon működik: for while do..while if...else switch..case..default break continue return Leglényegesebb különbségek: az if után álló feltétel mindig boolean típusú, azaz: int value; if (value) { ... } // Hiba! if (0 != value) { ... } // Így jó!
(nincs goto !!!) 30 / 59
Goto helyett címkézett ciklusok outer: while (true) { inner: while (true) { break; // kilép a belső ciklusból break inner; // kilép a belső ciklusból break outer; // kilép a külső ciklusból } } 31 / 59
Java osztályok specialitásai Minden osztálynak van: Konstruktora • feladata az objektum inicializálása • több konstruktor is tartozhat egy osztályhoz • minden alkalommal meghívódik amikor létrehozunk egy objektumot
közös őse: minden osztály az Object-ből származik (nem kell feltüntetni)
32 / 59
Java osztályok specialitásai Az osztályoknak nincs:
másoló konstruktora (helyette más mechanizmus) = operátora destruktora (helyette finalize)
33 / 59
Tagok Beágyazott objektum class Group { private Employee employees[]; int n_emp = 0; Group( ) { employees = new Employee[10]; }
Kezdeti érték Explicit helyfoglalás
void Add(Employee e) {employees[n_emp++] = e;} void Doctor( ) { for(int i = 0; i < n_emp; i++) { employees[i].name = new String(”Dr. ” + employees[i].name); } }
név belülről
Minősített elérés más objektumból 34 / 59
Metódusok Virtuális metódusok: nincs virtual kulcsszó, minden függvény virtuális ha mégsem akarjuk, hogy egy leszármazott felüldefiniálja, akkor a final kulcsszót használhatjuk Absztrakt metódus: az abstract kulcsszóval abstract class Shape { public abstract void draw(); // nincs törzs public final void move(int newX, int newY) { … } }
abstract metódusa csak abstract osztálynak lehet abstract osztály nem példányosodhat
35 / 59
Osztályváltozók C++
Java
class Dolgozo { int kor; static int nygdjkrhtr; int hatra() { return (nygdrkrhtr-kor); } };
class Dolgozo { int kor; static int nygdjkrhtr =65; int hatra() { return(nygdrkrhtr-kor); } }
Az osztály minden példányához tartozik, Külön kell inicializálni
int Dolgozo::nygdjkorhtr=65; 36 / 59
Osztálymetódusok C++
Java
class Window { static void WndProc(); }; … wnd.lpfnWndProc =WndProc; … RegisterClass( &wnd )
class Dolgozo { static int nygdjkrhtr =65; static void NyEmel( ) { nygdjkrhtr++; } } … Dolgozo.NyEmel();
lpfnWndProc
Windows esemény
WndProc() C,PASCAL függvény
Alkalmazás 37 / 59
Osztály változó és metódus A static kulcsszóval deklarált változók és metódusok nem egy objektumhoz tartoznak, hanem az egész osztályra közösek.
statikus függvények • csak statikus függvényeket és változókat használhatnak (nincs implicit this az argumentumok között) • meghívásukkor a pont elé nem egy objektum, hanem az osztály nevét kell írni: Dolgozo.NyEmel(); 38 / 59
A main függvény
Először a main függvény indul, az objektumokat ettől kezdve hozzuk létre Nincs még objektum (nem üzenhetünk senkinek) A main csak statikus lehet
public static void main(String args[]) { ... }
A main new-val létrehozhat lokális objektumokat, azokon kívül csak a statikus objektumokat érheti el 39 / 59
Statikus változók inicializálása Konstans értékadás: class Dolgozo { static int nygdjkrhtr = 65; } A statikus változóknak a static initializer adhat kezdőértéket: class AClass { static { // Nincs név, visszatérő érték, semmi // Itt csinálhatunk bármit } ... }
Hasonlít a konstruktorhoz, de nem egy példányt, hanem az 40 / 59 osztályt inicializálja
Statikus változók/metódusok jelentősége Statikus változó = „Objektum Orientált” globális változó Statikus függvény = „Objektum Orientált” globális függvény int i = Integer.MAX_VALUE; float rnd = Math.random(); float sinpi = Math.sin( Math.PI ); String s = String.valueOf( 123 ); System.out.println(“Az eredmeny”);
41 / 59
Adatrejtés
felesleges részletek és belső állapotok elrejtése különböző hozzáférési szintek • public mindenki számára hozzáférhető • package az adott package-be tartozó osztályok számára érhető el (alapértelmezett) • private csak az osztályon belülről érhető el legyen minden private, amíg nem indokolt publikussá tenni
42 / 59
Polimorfizmus
a paraméterek típusától függően másként viselkedő függvények void szamol(int ertek); void szamol(Complex ertek);
felüldefiniált függvény • a leszármazott osztályban ugyanazzal a névvel és paraméterekkel definiált függvény • @Override jelölő 43 / 59
Szemétgyűjtés Java-ban a létrehozott objektumokat nem kell a programnak explicit megsemmisítenie nincs destruktor nincs delete operátor van finalize() metódus: a szemétgyűjtő hívja a megsemmisítés előtt A felesleges objektumok eltüntetéséről a szemétgyűjtő (garbage collector) gondoskodik alacsony prioritással állandóan fut a háttérben figyeli, hogy mely objektumokra nincs már érvényes hivatkozás 44 / 59
Öröklődés Java módra
minden osztály az Object-ből származik egy osztálynak csak egy ősosztálya lehet (többszörös öröklődés nincs) a leszármazott osztály örökli a paraméter nélküli konstruktort a paraméteres konstruktorokat NEM! az ősosztály konstruktorát a super() segítségével hívhatjuk meg 45 / 59
Öröklődés Java módra
az osztály (class) mellett bevezeti az interface-t ez majdnem olyan, mint egy osztály, de: • csak publikus, absztrakt függvényeket tartalmaz • csak final változókat tartamaz • nem lehet példányosítani • az interfacet implementáló osztálynak az interface minden függvényét meg kell valósítani „ős-interface”-ből több is lehet egy osztálynak az őstípus mellett 46 / 59
Öröklődés abstract class shape { protected int x, y, col; void move(int dx, int dy) { int c = col; col = 0; draw(); x += dx; y += dy; col = c; draw(); } abstract void draw( ); shape( int x0, int y0, int c0 ) { x = x0; y = y0; col = c0; } } class line extends shape { private int xe, ye; line( int x1, int y1, int x2, int y2, int c ) { super( x1, y1, c ); xe = x2; ye = y2; } void draw( ) { … } 47 / 59 }
Öröklés szerepei C++ -ban
Kód, változó átörökítés class Shape { int x, y, col; void SetColor( int c ) { col = c; } }
class Line : public Shape { } class Rect : public Shape { }
Közös interfész megvalósítása: pl. heterogén szerk. class Shape { virtual void Draw()=0; } class Line : public Shape { virtual void Draw(); } class Rect : public Shape { virtual void Draw(); }
Shape * shapes[10]; shapes[0] = new Line(); shapes[1] = new Rect(); for(int i = 0; i < 2; i++) shapes[i] -> Draw( ); 48 / 59
A második funkció interfésszel interface ShapeLike { void Draw( ); } class Line implements ShapeLike { void Draw(); } class Rect implements ShapeLike { void Draw(); } ... void Display( ShapeLike s ) { s.Draw( ); } ... Display( new Rect() ); ... Display( new Line() );
49 / 59
Interface megvalósítás class Employee { … } class Manager extends Employee { … } interface TempLike { int GetTime( ); void SetTime( int t ); } class Temporary extends Employee implements TempLike { int emp_time; Temporary( String nam, long sal, int time ) { super(nam, sal); // for base class constructor emp_time = time; } public void Show( ) { super.Show( ); System.out.print(”Until "+String.valueOf(emp_time)); } public int GetTime( ) { return emp_time; } public void SetTime( int t ) { emp_time = t; } 50 / 59 }
TempMan
class TempMan extends Manager implements TempLike { int emp_time; TempMan( String nam, long sal, int time, int level ) { super(nam, sal, level); //for base class constructor emp_time = time; } public void Show( ) { super.Show( ); System.out.print(”Until "+String.valueOf(emp_time)); } public int GetTime( ) { return emp_time; } public void SetTime( int t ) { emp_time = t; } } 51 / 59
Az ősök őse: Object public class Object { public Object( ) { … } protected Object clone( ) { … } // “copy constructor”, ha nem definiáljuk át // csak belülről működik protected void finalize( ) { … } // “destruktor”, protected public boolean equals( Object o ) { … } // összehasonlítás public final Class getClass( ) { … } // melyik osztályból definiáltuk ezt: végleges public String toString( ) { … } // konverzió string-re (kiíráshoz) } 52 / 59
Példa: heterogén tömb public class MyArray { protected Object[] elements; MyArray(int size) { elements = new Object[size]; } Object getItem(int idx) { return elements[idx]; } void putItem( int idx, Object o ) { elements[idx] = o; } } 53 / 59
Öröklődés: Klónozható tömb public class MyCloneableArray extends MyArray { MyCloneableArray(int size) { super(size); // Őstípus konstruktora, először ezt kell hívni } public Object clone() { MyCloneableArray newArray = new MyCloneableArray(elements.length); for (int i = 0; i < elements.length; i++) newArray.elements[i] = elements[i]; return newArray; } }
54 / 59
Besorolás a klónozhatók csoportjába // public interface Cloneable { // public Object clone(); // }; public class MyCloneableArray extends MyArray implements Cloneable { MyCloneableArray(int size) { … } public Object clone() { MyCloneableArray newArray = new MyCloneableArray(elements.length); ... } } 55 / 59
Import, package-ek
Package: Java osztályok és al-package-ek halmaza package graphics; CLASSPATH public class Circle { ... graphics/ Circle.class }
Package vagy class importálása: import graphics.*; import java.lang.*; import java.applet.Applet; Azonos packageben levő osztályokat nem kell importálni Minden Java osztály egy package tagja 56 / 59
Fontos beépített package-ek java.applet Az Applet osztály és egyéb, appletekkel kapcsolatos eszközök java.awt (Abstract Windowing Toolkit) GUI osztályok: ablakok, ablak elemek java.awt.event Eseménykezeléssel kapcsolatos osztályok és interface-ek java.awt.image Képek megjelenítése, feldolgozása java.io File és más adatfolyamok kezelése 57 / 59
Fontos beépített package-ek II. java.lang Egyszerű adattípusok osztály megfelelői (Integer) Szálak (Thread) kezelése Stringek kezelése (String és StringBuffer) java.net Hálózatkezelés: Socket, URL, HTTP kapcsolat, stb. java.rmi (Remote Method Invocation) Távoli eljárások hívása (CORBA-szerű) java.util Kollekciók, naptár, helyi információk, stb.
És még nagyon sokan mások
58 / 59