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 class HelloWorldApp { public static void main(string[] args) { System.out.println("Hello World!"); HelloWorldApp.class 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 8-bites előjeles egész short 16-bites előjeles egész int 32-bites előjeles egész long 64-bites előjeles egész float 32-bites lebegőpontos (IEEE 754) double 64-bites lebegőpontos (IEEE 754) char 16-bites Unicode karakter boolean 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 { csomagból String name; A törzs csak az private long salary = 100; osztályon belül lehet osztályból public Employee(String n, long sal) { bárhonnan name = n; salary = sal; 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 { class Vector { int x, y; int x, y; ;.. Vector v; // stack-en Vector v = new Vector( ); Vector *pvnull = NULL; Vector pvnull; Vector *pv = &v; Vector pv = v; Vector& rv = v; Vector rv = v; Vector *pvd = new Vector(); Vector pvd = new Vector(); delete pvd; 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 A tömbjeiben elemek vannak Akárcsak a beépített típusok 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 referenciák vannak Nem úgy viselkedik, mint a beépített típusok int i, j=3; i = j; int array[10]; Class c; c.f( ); Class c1 = c; int * pi; Class* c;... pi = new int; c = new Class; *pi = 3; c->f( ); int * pj = pi; Class* c1 = c; 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 BEÉPÍTETT TÍPUSOK Dinamikus memóriából allokált Lehet null = referenciát másol nem adatot A tömbjeiben referenciák vannak OBJEKTUMOK int i, j=3; i = j; int array[10]; Class c; c.f( ); Class c1 = c; int * pi; Class c;... pi = new int; c = new Class; *pi = 3; c.f( ); int * pj = pi; Class c1 = c; int array[]; array = new int[10]; 17 / 59 Visszatérés objektummal C++ Java class Vector class Vector { { Vector Add(const Vector& v) public Vector Add(Vector v) { { return Vector(x + v.x, y + v.y); 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 nincs (1.5.0 Generics) 2. void pointer nincs pointer 3. Alaposztályra Mi az alaposztály: Object!!! mutató pointer vagy referencia 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 if (A instanceof B) {... 29 / 59 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[]; Kezdeti érték int n_emp = 0; Group( ) { employees = new Employee[10]; 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 { class Dolgozo { int kor; int kor; static int nygdjkrhtr; static int nygdjkrhtr =65; int hatra() { int hatra() { return (nygdrkrhtr-kor); 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 { class Dolgozo { static void WndProc(); static int nygdjkrhtr =65; ; static void NyEmel( ) { nygdjkrhtr++; wnd.lpfnwndproc =WndProc; RegisterClass( &wnd ) Dolgozo.NyEmel(); lpfnwndproc esemény Windows 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