Gyakorlati alapok III.
Interfész + öröklődés + egyenlőség
Az alábbi viszonylag egyszerű
példaprojektben az alcímben megfogalmazott programozástechnikai fogalmakat
valósítjuk meg. Kvázielméleti kiindulópontunk az
Isikidom interfész, amelyik most egyetlen, még elméleti, minden
síkidomra egységes, ezért általánosítható tulajdonságot tartalmaz, ez a
terület. (Természetesen lehetett volna a kerület is, de a jelen példában ennyi
elég.)
public interface ISikidom {
int terulet();
}
Emlékezzünk vissza: az implementáló osztályban az interfészben megfogalmazott
metódusfejet (itt terulet()) kötelezően ki kell
dolgozni. Ezzel elindul a specializálódás folyamata és ez nyilvánvalóan a
Negyzet osztály lesz, amelynek minden oldala
azonos hosszúságú, így elég 1 db osztályváltozót beállítanunk, ez lesz a
private int a. Ez az osztály
private módosítószóval védett, belső adata (A
hozzáférés-módosítók
című fejezet), őt pedig úgy óvjuk, hogy csakis különálló metódusokon
keresztül szólítható meg, ezek lesznek a getter-setter függvények (Get it and set it!
című fejezet).
A terulet() metódusfej kötelező kidolgozása az
a * a képlettel történik, de konkrét értéket
nyilvánvalóan nem itt fogunk neki adni, hanem a
Controller (A
Controller osztály lehetősége
című fejezet) vagy ehhez hasonló funkciójú osztályban; ebben a
projektben ezt a Main() osztály valósítja meg.
Ezt olyan módon tesszük meg, hogy a Negyzet
osztály konstruktor függvényét írjuk felül, amely során a konkrét
változóértéket bemeneti paraméterként kapja meg:
Negyzet(a).
public class Negyzet implements ISikidom {
private int a;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
Negyzet(int a) {
this.a = a;
}
@Override
public int terulet() {
return a * a;
}
}
A Teglalap osztályt nyilvánvalóan a
Negyzet osztályból örökítjük, ezáltal megkapja az
int a változót és a terulet()
metódust, amelyet azonban felül kell írnunk az a * b
képlettel (@override). A téglalap
b oldalának belső adatát (private
int b) a Negyzet osztályban említett módon
kell bekonfigurálnunk. Bár a Teglalap osztály
konstruktorában a super(a) segítségével
visszanyúltunk a Negyzet osztály belső
változójához, ezt ebben az osztályban már nem tudjuk máshol megtenni, mivel az
int a változó private
elérésű: az csakis a Negyzet osztályhoz tartozik,
azaz másik osztályból nem látható.
A megoldás a
this.getA() függvény meghívása, vagy ha a
Negyzet osztályban a változó elérést
private szóról protected
módosítószóra cseréljük.
public class
Teglalap extends Negyzet {
private int b;
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
Teglalap(int a, int b) {
super(a);
this.b = b;
}
public int terulet() {
return this.getA() * b;
}
}
A Main osztály említett módon egyfajta kontroller
osztályként működik (A
Controller osztály lehetősége
című fejezet): összefogja, példányosítja és egységesen lefuttatja az
osztályokat. Pontosan itt, a kontroller osztályban kell az oldalváltozóknak
konkrét értéket adni, például:
int a = 4;
int b = 3;
Ugyanakkor a Main osztályban lett kidolgozva az
equals() függvény is, amely a jelen esetben a
területeket hasonlítja össze. Visszatérési értéktípusa kötelezően
boolean, értéke pedig true,
ha a területek azonosak, false, ha nem. Vegyük
észre, hogy a Main osztályt
m referenciával példányosítottuk, nem a main
referenciával, nehogy bármilyen ütközés legyen a main()
főprogrammal (persze még nem lesz; ezzel kapcsolatban olvassuk el az
1 osztály +
több main() című fejezetet).
public class
Main {
boolean equals(double terulet1, double terulet2) {
boolean isEquals = false;
if(terulet1 == terulet2) {
isEquals = true;
return isEquals;
}
else
return isEquals;
}
public static void main(String[] args) {
int a = 4;
int b = 3;
Negyzet negyzet = new Negyzet(a);
Teglalap teglalap = new Teglalap(a, b);
Uzenet uzenet = new Uzenet();
Main m = new Main();
uzenet.terulet(negyzet, negyzet.terulet());
uzenet.terulet(teglalap, teglalap.terulet());
if(m.equals(negyzet.terulet(), teglalap.terulet())) {
uzenet.egyenlo();
}
else
uzenet.nemEgyenlo();
}
}
A magam részéről az üzeneteket is
külön osztályba tettem:
public class Uzenet {
public void terulet(Object o, int terulet) {
System.out.println("A " + o.getClass() + " területe: " +
terulet);
}
public void egyenlo() {
System.out.println("Az objektumok egyenlők.");
}
public void nemEgyenlo() {
System.out.println("Az objektumok nem egyenlők.");
}
}
Nézzük meg a futtatható Java-kódot:
ISikidom.java
public interface ISikidom {
int terulet();
}
Negyzet.java
public class Negyzet implements ISikidom {
private int a;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
Negyzet(int a) {
this.a = a;
}
@Override
public int terulet() {
return a * a;
}
}
Teglalap.java
public class Teglalap extends Negyzet {
private int b;
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
Teglalap(int a, int b) {
super(a);
this.b = b;
}
public int terulet() {
return this.getA() * b;
}
}
Uzenet.java
public class
Uzenet {
public void terulet(Object o, int terulet) {
System.out.println("A " + o.getClass() + " területe: " +
terulet);
}
public void egyenlo() {
System.out.println("Az objektumok egyenlők.");
}
public void nemEgyenlo() {
System.out.println("Az objektumok nem egyenlők.");
}
}
Main.java
public class Main {
boolean equals(double terulet1, double terulet2) {
boolean isEquals = false;
if(terulet1 == terulet2) {
isEquals = true;
return isEquals;
}
else
return isEquals;
}
public static void main(String[] args) {
int a = 4;
int b = 3;
Negyzet negyzet = new Negyzet(a);
Teglalap teglalap = new Teglalap(a, b);
Uzenet uzenet = new Uzenet();
Main m = new Main();
uzenet.terulet(negyzet, negyzet.terulet());
uzenet.terulet(teglalap, teglalap.terulet());
if(m.equals(negyzet.terulet(), teglalap.terulet())) {
uzenet.egyenlo();
}
else
uzenet.nemEgyenlo();
}
}
Végeredmény:
A class Negyzet területe: 16
A class Teglalap területe: 12
Az objektumok nem egyenlők.