[[:oktatas:programozás:java|< Java]]
====== Objektum Orientált Programozás Java nyelven ======
* **Szerző:** Sallai András
* Copyright (c) 2011, Sallai András
* Szerkesztve: 2011, 2013, 2014, 2019, 2021, 2023, 2024
* Licenc: [[https://creativecommons.org/licenses/by-sa/4.0/|CC Attribution-Share Alike 4.0 International]]
* Web: https://szit.hu
===== Osztályok =====
==== UML példa ====
{{:oktatas:programozás:java:ablakpelda.png|}}
{{:oktatas:programozás:java:tanulo_uml.png|}}
===== Egyszerű osztályhasználat =====
Alapértelmezetten mindig használunk egy osztályt, az alábbi példában ennek a neve "Program01":
public class Program01 {
public void kiir() {
System.out.println("Alma");
}
public static void main(String [] args) {
Program01 iro = new Program01();
iro.kiir();
}
}
===== Osztályok és metódusaik =====
Még mindig egyetlen osztályt használunk, amelyben több metódust és egy mezőt hozunk létre.
A mező neve Nev. A név mező tulajdonképpen egy String típusú változó. Ennek beállításra
és lekérdezésére hozunk létre egy setNev() és egy getNev() metódust.
public class Szemely {
//Adatmezők
private String nev;
//Metódusok
public void setNev(String n) {
nev = n;
}
public String getNev() {
return nev;
}
public static void main(String [] args) {
Szemely ember = new Szemely(); //Osztálynév Objektum = new Osztály_Konstruktor;
ember.setNev("Józsi");
System.out.println("Eredmeny: " + ember.getNev());
}
}
{{:oktatas:programozás:java:tobbmetodusosztalyban.png|}}
===== Gyakorlás =====
- Mire való egy osztályban a metódus?
- Milyen kulcsszóval kezdődik egy osztály?
- Írjon egy metódust, amely mindig 100-al tér vissza.
===== Több osztály =====
A következő példákban már létrehozunk más osztályokat is a főosztály mellett.
Ha lehet 1 állományban csak egy osztály legyen.
Ha mégis több osztályunk van, csak a főosztály legyen publikus.
==== Tulajdonságok szabad elérése ====
Alapesetben a tulajdonságok (mezők) szabadon elérhetők. Az objektumorientált programozásnak azonban
ez ellentmond.
public class Program01 {
public static void main(String args[]) {
Szemely tanulo1 = new Szemely();
tanulo1.nev = "Pista";
System.out.println(tanulo1.nev());
}
}
class Szemely {
String nev;
int kor;
String Hajszin;
}
{{:oktatas:programozás:java:egyfajltobbosztaly.png|}}
==== Tulajdonságok osztályba zárása ====
A következő példában az osztály mezőit bezárjuk (privát tagokká tesszük, azok csak metódusokkal változtathatók meg.)
public class Program01 {
public static void main(String args[]) {
Szemely tanulo1 = new Szemely();
tanulo1.adNev("Pista");
System.out.println(tanulo1.kerNev());
}
}
class Szemely {
//Adatmezők
private String nev;
private int kor;
//Metódusok
public void adNev(String nev) {
this.nev = nev;
}
public String kerNev() {
return this.nev;
}
}
A kor mezőnek is létrehozhatunk egy-egy metódust
public class Program01 {
public static void main(String args[]) {
Szemely tanulo1 = new Szemely();
tanulo1.adNev("Pista");
System.out.println(tanulo1.kerNev());
}
}
class Szemely {
//Adatmezők
private String nev;
private int kor;
//Metódusok
public void adNev(String nev) {
this.nev = nev;
}
public String kerNev() {
return this.nev;
}
public void adKor(String nev) {
this.nev = nev;
}
public String kerKor() {
return this.nev;
}
}
{{:oktatas:programozás:java:tulajdonsagokesmetodusok.png|}}
==== Konstruktor használata ====
A konstruktorral előkészíthetjük az osztályt. A konstruktor metódus valójában akkor is
létrejön ha azt nem deklaráljuk. Az osztály példányosításánál valójában ezt hívjuk meg:
Szemely tanulo1 = new Szemely();
Az alábbi példában konstruktort is létrehozzuk.
public class Program01 {
public static void main(String args[]) {
Szemely tanulo1 = new Szemely();
tanulo1.adNev("Pista");
System.out.println(tanulo1.kerNev());
}
}
class Szemely {
private String nev;
private int kor;
Szemely() {
this.nev = "Névtelen";
}
public void adNev(String nev) {
this.nev = nev;
}
public String kerNev() {
return this.nev;
}
}
Ha adNev metódust nem használjuk a nev mezőnek akkor is lesz értéke:
Szemely tanulo1 = new Szemely();
System.out.println(tanulo1.kerNev());
{{:oktatas:programozás:java:konstruktor.png|}}
==== Gyakorlat ====
- Mit jelent az, hogy egy metódus private?
- Mit jelent az, hogy egy metódus public?
- Mit jelent az, hogy egy metódus protected?
- Mi a szerepe a konstruktornak?
===== Osztályonként külön állomány =====
A nagyobb programokat külön állományokba tesszük.
Minden állomány egy-egy osztály:
class Szemely {
String name;
Integer age;
void setName(String inName) {
name = inName;
}
String getName() {
return name;
}
void setAge(Integer inAge) {
age = inAge;
}
Integer getAge() {
return age;
}
}
class Program01 {
public static void main(String args[]) {
Szemely Pista = new Szemely();
Pista.setName("Nagy István");
System.out.println(Pista.getName());
}
}
{{:oktatas:programozás:java:ketosztalymetodusai.png|}}
===== Objektumok és a statikus metódus =====
Az osztályokat kétféle módon használhatjuk: példányosítjuk őket,
vagy az osztály nevén meghívjuk a metódust. Egy osztály nevén
olyan metódusokat hívhatunk meg, amelyeket statikusnak adtunk
meg.
{{:oktatas:programozás:java:peldanyesstatikusmetodus.png|}}
A követkeő példában az Osztaly1 osztályból létrehozok egy o1 nevű
objektum példányt. Ezek után az objektumon meghívhatjuk a metódust.
public class Osztaly1 {
public void m1() {
System.out.println("Helló Világ!");
}
}
public class Program01 {
public static void main(String[] args) {
Osztaly1 o1 = new Osztaly1();
o1.m1();
}
}
Ha egy osztály egyik metódusát static kulcsszóval statikussá
tesszük, az osztály nevén is meghívhatjuk a metódust.
public class Osztaly2 {
public static void m1() {
System.out.println("Helló Világ!");
}
}
public class Program01 {
public static void main(String[] args) {
Osztaly2.m1();
}
}
===== Hozzáférési szintek =====
Láthattuk, hogy a metódusaink, osztályaik elé néha public, private, stb. módosítókat teszünk.
A public egy metódus előtt azt jelenti, hogy más osztályokból is elérhetők, sőt más csomagokból,
de tulajdonképpen bárhonnan elérhetők. A private, azt jeleneti, csak az aktuális osztályból érhetők
el. A protected elérhető, a saját osztályból, azok alosztályaiból és az aktuális csomagból, de
más csomagokból már nem. Ha nem adunk meg módosítót, akkor csak a saját osztályból és a saját
csomagból érhető el.
^ Hozzáférési szintek ^^^^^
^ Módosító ^ Osztály ^ Csomag ^ Alosztály ^ Világ ^
| public | igen | igen | igen | igen |
| protected | igen | igen | igen | nem |
| nincs módosító | igen | igen | nem | nem |
| private | igen | nem | nem | nem |
===== Nested Osztályok =====
==== A nested osztályról ====
A Java programozási nyelv megengedi, hogy egy osztályban egy másik osztályt definiáljunk.
Az ilyen osztályt úgy hívjuk, hogy nested class (osztály) és az alábbiakban látunk rá egy példát:
class OuterClass {
...
class NestedClass {
...
}
}
==== Terminológia ====
A nested osztályból kétféle van: statikus és nem-statikus (static és non-static).
Ha egy nested osztályt statikusnak deklarálunk, akkor a neve szimplán nested osztály.
Ha nem statikus, akkor inner osztály.
class OuterClass {
...
static class StaticNestedClass {
...
}
class InnerClass {
...
}
}
A nested osztály egy zárt osztály tagja. A nem-statikus nested osztályok (inner) hozzáférnek más zárt osztályok tagjaihoz,
még ha azok privátnak vannak deklarálva is. A statikus nested osztályok nem férnek hozzá más zárt osztályok tagjaihoz.
Mint egy OuterClass tagja, egy nested osztály deklarálható private, public, protected, vagy csomag (package) private módon.
Az outer osztályok csak public vagy pacakage private módban deklarálhatók.
==== Miért használjunk Nested Osztályt? ====
Több ok is létezik, amiért nested osztályt érdemes használni:
* Az osztályokat csoportosítjuk és egy helyen kezeljük
* Egymásba ágyazzuk az osztályokat
* A nested osztályok olvashatóbb és karbantarthatóbb kódot eredményeznek.
==== Nested osztály példa ====
class Program01 {
public static void main(String args[]) {
Szemely pista = new Szemely();
pista.setName("Nagy István");
System.out.println(pista.getName());
}
static class Szemely {
String name;
Integer age;
public Szemely() {}
void setName(String inName) {
name = inName;
}
String getName() {
return name;
}
void setAge(Integer inAge) {
age = inAge;
}
Integer getAge() {
return age;
}
}
}
===== Öröklés =====
Ha már van egy osztályunk és szeretnénk azt kibővíteni az eredeti megtartása
mellett, akkor az új osztályunkba az eredeti osztály összes tagját
átörökítjük. A Java ezt a extends kulcsszóval képes végrehajtani.
Szabály, hogy egy osztály csak egy darab másik osztályból örökölhet.
A következő meglévő Szemely osztályból szeretnénk egy Dolgozó osztály készíteni,
amelyben már több tulajdonság van tárolva, a Szemely osztályhoz képest.
class Szemely {
String nev;
int kor;
}
class Dolgozo extends Szemely {
String munkakor;
double fizetes;
}
class Program01 {
public static void main(String args[]) {
Dolgozo joska = new Dolgozo();
joska.nev = "Nagy Jozsef";
joska.kor = 35;
joska.munkakor = "programozó";
joska.fizetes = 870000;
System.out.println(joska.kor);
}
}
A Dolgozo osztályból további öröklés lehetséges:
class Szemely {
String nev;
int kor;
}
class Dolgozo extends Szemely {
String munkakor;
double fizetes;
}
class Mernok extends Dolgozo {
String diplomaSzam;
}
class Doktor extends Mernok {
String phdSzam;
}
class Program01 {
public static void main(String args[]) {
Mernok joska = new Mernok();
joska.nev = "Nagy Jozsef";
joska.kor = 35;
joska.munkakor = "programozó";
joska.fizetes = 870000;
joska.diplomaSzam = "ABC3483";
System.out.println(joska.kor);
}
}
===== Abstract osztály =====
Az abstract osztályokat eleve öröklésre szánjuk, tehát nem hozható belőle létre példány.
* Az abstract osztály metódusainak törzsét nem lehet megvalósítani, ha maga a metódus is abstract.
* Az örökölt osztályban viszont kötelező megvalósítani, ha csak nem az is abstarct.
* Egy metódus csak akkor lehet abstract, ha maga az osztály is abstract.
* Egy abstract osztály metódusainak nem kötelező abstractnak lenni.
* Az abstract osztályt nem lehet final és privat módosítóval ellátni.
abstract class Dolgozo {
String nev;
int kor;
}
class Mernok extends Dolgozo {
String diplomaAz;
}
class Lapatos extends Dolgozo {
String szerszam;
}
class Program {
public static void main(String args[]) {
Lapatos joska = new Lapatos();
joska.kor = 35;
joska.szerszam = "szívlapát";
System.out.println("Jóska szerszáma: " + joska.szerszam);
}
}
Ha megpróbáljuk a példában szereplő Dolgozo osztályt példányosítani, akkor hibaüzenetet kapunk.
===== Többalakúság =====
Egy metódus alakja, annak paramétereit és visszatérési értékét jelenti.
class Dolgozo {
String nev;
int kor;
void beallitKor(int atvettKor) {
kor = atvettKor;
}
void beallitKor(double atvettKor) {
kor = Double.valueOf(atvettKor).intValue();
}
void beallitKor(String atvettKor) {
kor = Integer.parseInt(atvettKor);
}
}
class Program {
public static void main(String args[]) {
Dolgozo joska = new Dolgozo();
joska.beallitKor("5");
}
}
class Dolgozo {
String nev;
int kor;
void beallit(int atvettKor) {
kor = atvettKor;
}
void beallit(double atvettKor) {
kor = Double.valueOf(atvettKor).intValue();
}
void beallit(String atvettKor) {
kor = Integer.parseInt(atvettKor);
}
void beallit(int atvettKor, String atvettNev) {
kor = atvettKor;
nev = atvettNev;
}
}
class Program {
public static void main(String args[]) {
Dolgozo joska = new Dolgozo();
joska.beallit(35, "Nagy Péter");
}
}
A következő példában a konstruktornak adunk több alakot:
class Szemely {
String nev;
int kor;
public Szemely() {
nev = "Névtelen";
kor = 0;
}
public Szemely(String atvettNev) {
nev = atvettNev;
kor = 0;
}
public Szemely(int atvettKor){
nev = "Névtelen";
kor = atvettKor;
}
public Szemely(String atvettNev, int atvettKor){
nev = atvettNev;
kor = atvettKor;
}
}
class Program01 {
public static void main(String args[]) {
Szemely joska = new Szemely();
Szemely pista = new Szemely("Kis Pista");
Szemely kati = new Szemely(25);
Szemely mari = new Szemely("Nagy Mária", 25);
}
}
==== Többalakú osztályok ====
A többalakúság igazi példáját a többalakú osztályok adják.
Mivel minden örökölt példányban átírhatom a metódusokat, ezért
minden egyes örökölt osztályban mást és mást tehetnek a metódusok.
class Allat {
String gyomor = "";
public void eszik(String etel) {
gyomor += etel;
}
public void beszel() {
System.out.println("aaa");
}
}
class Szamar extends Allat {
public void beszel() {
System.out.println("ia\'ia\'");
}
}
class Boci extends Allat {
public void beszel() {
System.out.println("buuuuuuuuuu");
}
}
class Program01 {
public static void main(String[] args) {
Szamar pici = new Szamar();
pici.beszel();
Boci mici = new Boci();
mici.beszel();
}
}
==== Elvont osztály és metódus ====
A többalakúság igazi kiszolgálói az elvont osztályok és metódusok.
abstract class Allat {
String gyomor = "";
public void eszik(String etel) {
gyomor += etel;
}
public abstract void beszel();
}
class Szamar extends Allat {
public void beszel() {
System.out.println("ia\'ia\'");
}
}
class Boci extends Allat {
public void beszel() {
System.out.println("buuuuuuuuuu");
}
}
class Program01 {
public static void main(String[] args) {
Szamar pici = new Szamar();
pici.beszel();
Boci mici = new Boci();
mici.beszel();
}
}
Mivel az **Allat** osztályt elvonttá nyilvánítottam az **abstract** módosítóval, ezért
ebből az osztályból nem lehet példányt létrehozni.
Az **Allat** osztály **beszel()** metódusa szintén elvont, azaz abstract, ezért
kötelező felülírni a metódust. Az eredeti osztályban (Esetünkben az "Allat") nem is
lehet törzse, csak a fejrészt kell megadnunk.
===== Interface =====
==== Az interfacekről ====
Az interface-ek egy szabványos parancshalmazt definiálnak, amit az osztályok használhatnak.
Az osztály implementálja az interfészt. A parancsok metódusokból állnak.
Egy interfész a következőket tartalmazhat:
* metódus deklaráció
* nevesített állandó
* visszatérés típusa
* argumentum aláírása
* módosítók
Az osztálynak az interfész összes metódusát deklarálnia kell. Egy interface tehát olyan, mintegy abstract osztály, amelynek minden metódusa abstract.
Az interface nem rendelkezik szülő osztállyal, sem ősosztállyal, még rejtett módon sem, ellentétben az osztályokkal. Ez jól megfigyelhető a Java dokumentációban is. Minden osztálynak le van vezetve az öröklési hierarchiája, de az interfészeknek (interface) nincs ilyen.
==== Az állatos példa ====
Fentebb az abstract osztályokat és metódusokat tárgyaltuk. Ha egy osztály
minden metódusát abstract módosítóval látok el, akkor az örökölt osztályban
az összes metódust meg kell valósítani. Az ilyen szerkezetek helyett használhatjuk
az interface-t.
interface Allat {
public void eszik(String etel);
public abstract void beszel();
}
class Szamar implements Allat {
String gyomor = "";
public void eszik(String etel) {, ott minden metódus virtuális.
gyomor += etel;
}
public void beszel() {
System.out.println("ia\'ia\'");
}
}
class Boci implements Allat {
String gyomor = "";
public void eszik(String etel) {
gyomor += etel;
}
public void beszel() {
System.out.println("buuuuuuuuuu");
}
}
class Program01 {
public static void main(String[] args) {
Szamar pici = new Szamar();
pici.beszel();
Boci mici = new Boci();
mici.beszel();
}
}
A interfaceben nem lehet példányváltozót létrehozni, csak állandót.
==== Kerekparos interface példa ====
interface Kerekpar {
void beallitUtem(int ujUtem);
void novelSebesseg(int novekmeny);
void huzFek(int csokkentes);
}
class HauserKerekpar implements Kerekpar {
private int utem = 0;
public void beallitUtem(int ujUtem) {
utem = ujUtem;
}
public void novelSebesseg(int novekmeny) {}
public void huzFek(int csokkentes) {}
public int lekerUtem() {
return utem;
}
}
class Program01 {
public static void main(String args[]) {
HauserKerekpar kerekpar = new HauserKerekpar();
kerekpar.beallitUtem(1);
System.out.println(kerekpar.lekerUtem());
}
}
==== Udvarias személy interface példa ====
interface UdvariasSzemely {
void koszon();
}
class Szemely implements UdvariasSzemely {
String nev;
int kor;
public void koszon(){
System.out.println("Szia!");
}
}
class Program04 {
public static void main(String args[]) {
Szemely pista = new Szemely();
pista.koszon();
}
}
==== Alakzatrajzoló interface példa ====
interface Alakzat {
void beallitMeret(int szelesseg, int magassag);
void rajzol();
}
class Tegla implements Alakzat {
int szelesseg;
int magassag;
public void beallitMeret(int szelesseg, int magassag){
this.szelesseg = szelesseg;
this.magassag = magassag;
}
public void rajzol(){
for(int i=0;i
==== Többalakú interfész ====
public class Projekt01 {
static void rajzolAlakzat(Alakzat alakzat) {
alakzat.rajzol();
}
public static void main(String[] args) {
rajzolAlakzat(new Haromszog());
rajzolAlakzat(new Kor());
rajzolAlakzat(new Teglalap());
}
}
public class Haromszog implements Alakzat {
public void rajzol() {
System.out.println("A");
}
}
public class Kor implements Alakzat {
public void rajzol() {
System.out.println("o");
}
}
public class Teglalap implements Alakzat {
public void rajzol() {
System.out.println("E");
}
}
public class Projekt01 {
static void rajzolAlakzat(Alakzat alakzat) {
alakzat.rajzol();
}
public static void main(String[] args) {
rajzolAlakzat(new Haromszog());
rajzolAlakzat(new Kor());
rajzolAlakzat(new Teglalap());
}
}
===== A this =====
A this kulcsszó azt az osztályt reprezentálja, amelyben vagyunk.
class Dolgozo {
public String name;
public Dolgozo() {
String name = "untitled";
this.name = name;
}
}
class Program02 {
public static void main(String[] args) {
Dolgozo joska = new Dolgozo();
System.out.println(joska.name);
}
}
A példánkban a Dolgozo osztály name mezője nem venné fel a Dolgozo() konstruktorban létrehozott name változó értékét,
ha nem tettük volna az értékadás elejére a "this" szót. A program nélküle is lefordul, de az eredmény null lenne.
==== Gyakorlat ====
- Mire használható a this kulcsszó?
- Ha egy osztály egyik tagjára hivatkozok a this kulcsszóval, mi a szeparátor?
===== A super használata =====
class Dolgozo {
String Nev;
int Fizetes;
void beallitKezdoFizetes() {
Fizetes = 300100;
}
}
class Mernok extends Dolgozo {
void beallitKezdoFizetes() {
Fizetes = 500000;
}
}
class Program {
public static void main(String args[]) {
Mernok joska = new Mernok();
joska.beallitKezdoFizetes();
System.out.println(joska.Fizetes);
}
}
A beallitKezdoFizetes() metódust felülírjuk a Mernok osztályban.
Ekkor az eredeti beallitKezdoFizetes() rejtett marad a Mernok
osztályban.
Van azonban lehetőség az eredeti metódus meghívására is:
class Dolgozo {
String Nev;
int Fizetes;
void beallitKezdoFizetes() {
Fizetes = 300100;
}
}
class Mernok extends Dolgozo {
void beallitKezdoFizetes() {
super.beallitKezdoFizetes();
Fizetes = Fizetes + 200000;
}
}
class Program {
public static void main(String args[]) {
Mernok joska = new Mernok();
joska.beallitKezdoFizetes();
System.out.println(joska.Fizetes);
}
}
Az eredeti metódust a super.beallitKezdoFizetes(); utasítással hívom meg.
Így megkapom a dolgozó alapfizetését és a mérnők számára ahhoz tudom
hozzáadni a fizetést.
===== Metódus felülírása =====
Ha létrehozok egy osztályt az örökölés során a metódusokat felülírhatjuk.
A felülírható metódusokat virtuális metódusnak nevezzük. A Java nyelvben
minden példánymetódus eleve virtuális, nem kell azt jelezni külön
módosítóval.
Ha felülírunk egy metódust, akkor illik oda írni a "@Override" kulcsszót,
de nem kötelező. Ha azonban oda írjuk fordításkor kiderülhet, ha elírtuk
az átírandó metódus nevét, ezért érdemes mindig kiírni. Ezen felül
vizuálisan is azonnal kiderül számunkra, hogy felülírtunk egy már
meglévő metódust.
class Dolgozo {
String nev;
int kor;
double fiz;
public void alapfizetes() {
this.fiz = 80000;
}
}
class Mernok extends Dolgozo {
@Override
public void alapfizetes() {
this.fiz = 350000;
}
}
class Program01 {
public static void main(String args[]) {
Mernok lali = new Mernok();
lali.alapfizetes();
System.out.println(lali.fiz);
}
}
A következő példában a toString() metódust írjuk felül, amelyet minden osztály az Object osztálytól örököl:
class Dolgozo {
String nev;
int kor;
double fiz;
Dolgozo(String nev, int kor, double fiz) {
this.nev = nev;
this.kor = kor;
this.fiz = fiz;
}
@Override
public String toString() {
return nev + " " + kor + " " + fiz;
}
}
class Program01 {
public static void main(String args[]) {
Dolgozo joska = new Dolgozo("Nagy József", 35, 350000);
System.out.println(joska.toString());
}
}
===== Csomag =====
Az összetartozó osztályokat csomagokba rendezzük.
Készítsünk például egy "Jatek" nevű könyvtárat, majd helyezzük el
benne a következő két fájlt:
package Jatek;
public class Human {
void mutat() {
System.out.println("Ember");
}
}
package Jatek;
public class Gep {
public void mutat() {
System.out.println("Gép");
}
}
Mindkét fájl elejére a "package Jatek;" utasítást írtam.
A package utasítás csak a forrásfájl elején lehet.
Ezzel jelzem, hogy összetartozó névterekről van szó.
Tulajdonképpen nevet adtam a névtérnek.
Fordítsuk le mindkét osztályt:
javac Gep.java
javac Human.java
Most készítsünk egy névtelen névtérben egy osztály, mint azt eddig is tettük:
import Jatek.Gep;
class Program {
public static void main(String[] args) {
Gep gep = new Gep();
gep.mutat();
}
}
Az első sorban importáltuk a Jatek csomagból a Gep osztályt.
A szokásos módon használjuk tovább.
^ Csomag ^
| Jatek |
^ Az osztály egyszerű neve ^
| Gep |
^ Az osztály minősített neve ^
| Jatek.Gep |
Ha egy osztály több csomagban is szerepel és csoportosan importáltunk (Pl.: Jatek.*), akkor
előfordul, hogy a minősített nevet kell használnunk. A minősített név tulajdonképpen a
csomag teljes útvonala.
Újabb példa:
^ Csomag ^
| java.lang |
^ Az osztály egyszerű neve ^
| System |
^ Az osztály minősített neve ^
| java.lang.System |
Megkötés, hogy ha csomagon belül nem lehet ugyanolyan nevű osztály is, és
nem használhatunk a java vagy javax kezdetű csomagneveket.
Ha szeretném elkerülni más gyártókkal való ütközést, akkor esetleg egy
hu.szit.java.jatek
nevű névtérbe rendezem az osztályaim.
{{:oktatas:programozás:java:csomagok.png|}}
===== Módosítók =====
==== Hozzáférés vezérlés ====
* Nincs módosító. Az alapértelmezett elérés public.
* public - Az egész világ számára publikus
* private - Csak az osztályon belül érhető el.
* proteced - Csomagon belül és a származtatott osztályokban.
==== Egyéb módosítók ====
* static - osztálymetódus és osztályváltozó létrehozására
* final - osztály, metódus vagy változó véglegesítése
* abstract - absztrakt osztály vagy metódus létrehozása
* synchronized, volatile - szálaknál használatos
===== Sorosítás =====
Ha egy objektum állapotát szeretnék eltárolni akkor sorosítjuk, majd egy objektumkimeneti folyammal kiírom,
fájlkimeneti adatfolyamon keresztül. A visszaolvasás hasonlóan történik, amihez szintén szükséges a
sorosított objektum.
import java.io.*;
class Dolgozo implements Serializable {
String nev;
Integer kor;
}
class Program01 {
private static void make() throws IOException {
Dolgozo joska = new Dolgozo();
joska.nev = "Nagy József";
joska.kor = 35;
Dolgozo mari = new Dolgozo();
mari.nev = "Kis Mária";
mari.kor = 28;
FileOutputStream fs = new FileOutputStream("adat.dat");
ObjectOutputStream os = new ObjectOutputStream(fs);
os.writeObject(joska);
os.writeObject(mari);
os.close();
}
private static void load() throws IOException, ClassNotFoundException {
Dolgozo joska = null;
Dolgozo mari = null;
FileInputStream fs = new FileInputStream("adat.dat");
ObjectInputStream os = new ObjectInputStream(fs);
joska = (Dolgozo) os.readObject();
mari = (Dolgozo) os.readObject();
os.close();
System.out.println("Név: " + joska.nev);
System.out.println("Név: " + mari.nev);
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
//~ make();
load();
}
}
===== Példák =====
==== Példa 001 ====
Létrehozok egy dolgozó osztályt, majd a főmetódusban egy
munkas nevű tömböt, amelyben Dolgozókat lehet tárolni.
Egyetlen dolgozó nevét és életkorát beállítom.
class Dolgozo {
private String Nev;
private int Kor;
public void beallitNev(String atvettNev) {
Nev = atvettNev;
}
public String lekerNev() {
return Nev;
}
public void beallitKor(int atvettKor) {
Kor = atvettKor;
}
public int lekerKor() {
return Kor;
}
}
class Program {
public static void main(String[] argv) {
Dolgozo[] munkas = new Dolgozo[100];
for(int i=0; i<100; i++)
munkas[i] = new Dolgozo();
munkas[0].beallitNev("Joska");
munkas[0].beallitKor(30);
System.out.println(munkas[0].lekerNev());
System.out.println(munkas[0].lekerKor());
}
}
==== Példa 002 ====
import java.util.Scanner;
abstract class Eloleny {
protected StringBuilder emesztoRendszer = new StringBuilder("sav");
protected int uritesigHatra = 4;
public abstract void eszik(String kaja);
public abstract void urit();
}
class Kisallat extends Eloleny {
public void eszik(String kaja) {
this.emesztoRendszer.append(kaja);
}
public void urit() {
System.out.print("Űrítek: ");
System.out.println(this.emesztoRendszer.substring(0, 4));
this.emesztoRendszer.delete(0, 4);
}
}
class Program01 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Kisallat pamacs = new Kisallat();
System.out.println("Van egy Pamacs nevű kis állatod. Időnként etetned kell az etet paranccsal.");
System.out.println("Pamacs mindenféle karakter eszik. A \"etet\" parancs után ad meg mit adsz neki.");
String cmd = null;
do {
System.out.print("> ");
cmd = in.nextLine();
if(cmd.matches("etet .+")) {
String[] t = cmd.split(" ");
pamacs.eszik(t[1]);
}
if(pamacs.uritesigHatra<=0) {
pamacs.urit();
pamacs.uritesigHatra = 5;
}
pamacs.uritesigHatra--;
}while(!cmd.equals("vege"));
}
}
==== Példa 003 ====
Az önálló nyomógomb megvalósítása.
import javax.swing.JButton;
import javax.swing.JTextField;
import javax.swing.JFrame;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.FlowLayout;
class SzamitGomb extends JButton implements ActionListener {
JTextField mezo;
SzamitGomb(JTextField mezo) {
this.setText("Klikkelj ide");
this.addActionListener(this);
this.mezo = mezo;
}
public void actionPerformed(ActionEvent event) {
this.mezo.setText("Teszt ok");
}
}
class FoAblak extends JFrame {
SzamitGomb szamitGomb;
JTextField mezo;
FoAblak() {
this.mezo = new JTextField(10);
this.szamitGomb = new SzamitGomb(mezo);
this.add(szamitGomb);
this.add(mezo);
this.setLayout(new FlowLayout());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(400, 300);
this.setVisible(true);
}
}
class Program01 {
public static void main(String args[]) {
new FoAblak();
}
}
==== Példa 004 ====
A világon számtalan kerékpár létezik, de mindegyiknek vannak közös állapotaik, közös jellemzőik.
Az objektum-orientál világban azt mondjuk, a kerékpár egy osztály. Egy konkrét kerékpár a kerékpár
osztálynak egy példánya. Tehát az osztály tulajdonképpen egy terve, amelyből létrehozzuk a
konkrét kerékpárokat.
class Kerékpár {
int ütem = 0;
int sebesség = 0;
int fokozat = 1;
void cserélLépésÜtem (int újÉrték) {
ütem = újÉrték;
}
void cserélSebességFokozat (int újÉrték) {
hajtómű = újÉrték;
}
void sebességNövelés (int növekmény) {
sebesség = sebesség + növekmény;
}
void alkalmazFékezés (int csökkentő) {
sebesség = sebesség - csökkentő;
}
void állapotNyomtatása () {
System.out.println ("ütem: " + ütem + "sebesség: " + sebesség + "fokozat: " + fokozat);
}
}
==== Példa 005 ====
Objektum példák.
Az objektum a kulcsa az objektum-orientált programozás megértésének. Néz körül az életedben, nagyon sok
példát találsz az objektumokra. Az asztal, a kutya, a bicikli, stb.
Minden objektumnak van valamilyen állapota. Ezek az állapotok időnként változnak.
=== Kutya objektum ===
* állapotai
* van neve: Bodri
* éhes: igen
* színe: fekete
* stb.
* állapot megváltozása
* eszik
* alszik
* ugat
* hízeleg
* csóválja a farkát
* stb.
=== Kerékpár ===
* állapotai
* kék
* az aktuális sebessége
* viselkedése
* gyorsul
* fékezés történik
=== Asztali lámpa ===
* állapotai
* fel van kapcsolva
* le van kapcsolva
* viselkedése
* felkapcsoljuk
* lekapcsoljuk
=== asztali rádió ===
* állapotai
* az aktuális állomáson van
* valamilyen hangerő be van éppen állítva
* üzem (be van kapcsolva, ki van kapcsolva)
* viselkedés
* bekapcsoljuk
* kikapcsoljuk
* állomást keresünk
* hangerőt állítunk
A valós világ egyes objektumai további objektumokat tartalmazhatnak.
Így van ez a szoftveres objektumok esetén is. Vannak objektumok,
bizonyos mezőkkel (állapotokkal) és vannak metódusok (viselkedés).