Gyakorlati alapok III.

Az interfész alapszintű működése egy példán keresztül

 

Ismételjük meg az előző fejezet egyik legfontosabb megállapítását:

 

www.informatika-programozas.hu - Ezt most meg kell tanulni!

 

Kódredundancia helyett az osztályhierarchiában több, funkcionalitásában, működésében különböző (azaz különböző tulajdonságú) osztályt fogunk találni, amelyek között egyfajta hídként az interfész lehetőségét használhatjuk fel, ha 2 különböző osztály között közös tulajdonságokat akarunk kialakítani.


Tehát az interfész alapértelmezésben híd, másképpen fogalmazva a közös tulajdonság (vagy közös tulajdonságok csoportja) a különböző tulajdonságú osztályok között. Erre fogunk látni az alábbiakban 1 viszonylag egyszerű példát.

Mindenekelőtt azonban hangsúlyozni szeretném, hogy a példa alaphelyzete meglehetősen elméleti. Szinte egészen bizonyos, hogy nem az alábbiak szerint kell az osztályok funkcióit kialakítani, de ne felejtsük el, hogy mi most csupán érthető példával igyekszünk megbirkózni, nem pedig kísérletet teszünk 1 osztályhierarchia kialakítására.
 

Új, Kor névvel ellátott projekt alkotása után a következő programelemeket alkotjuk meg:

Nem nehéz észrevennünk a KorTeruletOsszegzo és KorTeruletAtlagolo osztályok közös tulajdonságait. Mindkettő körrel és annak területével készül dolgozni, tehát ezen programelemeket interfész segítségével fogjuk implementálni:

www.informatika-programozas.hu - Ezt most meg kell tanulni!

 

Az interfész konstansokat és metódusfejeket definiál azon célból, hogy a későbbiekben azt az implementáló osztályban teljes egészében kidolgozzuk. Sőt, interfész deklarálása esetén a metódusokat ott egyenesen kötelező kidolgoznunk, másként fordítási hibát kapunk.
 

Először nézzük meg az interfész implementációját, amelyet utána szét is boncolunk. A projekt létrehozása után, a src mappában, automatizált körülmények között tudjuk létrehozni az interfészt:

 

www.informatika-programozas.hu - Interfész

 

Az interfész kötelezően public, hiszen nincs értelme felhasználni, ha nem is látható (azaz elveszíti híd-jellegét). Ha nem adjuk meg a public hozzáférés-módosítást, akkor láthatósága csomagszintű.

 

Az interfész alapértelmezésben abstract, azaz nem példányosítható. Igazából nem is tudjuk ezt megtenni, mert nem működőképes kód, csak "emlékeztetőket" tartalmaz arra vonatkozóan, hogy mit is kell majd kidolgoznunk az implementáló osztályban. Az emlékeztetők pedig azok a metódusfejek, amelyeknek az interfészen belül nincs műveleti blokkjuk, a mi esetünkben például:

 

double korTerulet(int sugar, double PI);

 

A metódusfej tehát leginkább a művelet szignatúrájához hasonlít.

 

Ha az interfész konstansokat is tartalmaz, akkor a konstansok módosításai -akár kitesszük, akár nem-, public, static, final, ezt nem tudjuk befolyásolni.

 

Nézzük meg az interfész implementációját:

 

import java.math.*;

public interface IKorTulajdonsagok {
    double PI = Math.PI;
    int korSzam = 10;
    double korTerulet(int sugar, double PI);
}

 

www.informatika-programozas.hu - Ezt most meg kell tanulni!

 

Nem oly szigorú, de sok helyen elvárt névadási konvenció az interfészek kezdőneveit nagy I betűvel kezdeni, itt: IKorTulajdonsagok.

 

double PI = Math.PI;

Nem túl elegáns egy már meglévő konstans értéket (Math.PI) másikba átvezetni (double PI). Ezt most azért tettem így, hogy a későbbiekben lássuk, milyen egyszerűen hivatkozhatunk az általunk kreált konstansokra az interfész felhasználásával.

 

int korSzam = 10;

Ez egy másik konstans, bár nem közvetlenül tartozik ide, inkább csak a példa kedvéért tettük konstanssá.

 

double korTerulet(int sugar, double PI);

A metódusfej, mint "emlékeztető" arra vonatkozóan, hogy mit kell a későbbiekben kidolgoznunk az implementáló osztályban.

 

Ezután fel kell építenünk az implementáló osztály(ok)at. Az interfészt az implementáló osztályba az implements szóval vezetjük be. Először nézzük meg a KorTeruletOsszegzo osztályt:

 

public class KorTeruletOsszegzo implements IKorTulajdonsagok{

KorTeruletOsszegzo(){
    System.out.println(osszegzo());
};

@Override
public double korTerulet(int sugar, double PI){
    return (sugar * sugar) * PI;
}

public double osszegzo(){
    double korTeruletOsszeg = 0;
    for(int i = 1; i <= korSzam; i++){
        int sugar = i;
        korTeruletOsszeg += korTerulet(sugar, PI);
        System.out.println(sugar + " egység sugarú kör területe: " + korTerulet(sugar, PI));
    }
    System.out.print("Körterületek összege: " + korTeruletOsszeg);
    return korTeruletOsszeg;
    }
}

 

Az @Override intelligens annotáció jelzi, hogy kötelező kidolgoznunk a metódust és hibaüzenettel addig nem is hagy minket békén, ameddig ezt nem tesszük meg.

 

www.informatika-programozas.hu - Annotáció

 

Ugyanezen lépéseket kell megtennünk a KorTeruletAtlagolo osztállyal kapcsolatban is: 

 

public class KorTeruletAtlagolo implements IKorTulajdonsagok{

KorTeruletAtlagolo(){
    System.out.println(atlagolo());
};

@Override
public double korTerulet(int sugar, double PI){
    return (sugar * sugar) * PI;
}

public double atlagolo(){
    double korTeruletOsszeg = 0;
    for(int i = 1; i <= korSzam; i++){
        int sugar = i;
        korTeruletOsszeg += korTerulet(sugar, PI);
        System.out.println(sugar + " egység sugarú kör területe: " + korTerulet(sugar, PI));
    }
    System.out.print("Körterületek átlaga: " + korTeruletOsszeg / korSzam);
    return korTeruletOsszeg / korSzam;
    }
}

 

A Main osztályban a fenti 2 osztály példányosítása a konstruktor függvényeik rafinált felülírásával valósul meg, amely által a kódfuttatás egyszerűbbé válik:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
public static void main(String[] args) {
    new KorTeruletOsszegzo();
    System.out.println();
    new KorTeruletAtlagolo();
    }
}

 

Végeredmény:

1 egység sugarú kör területe: 3.141592653589793
2 egység sugarú kör területe: 12.566370614359172
3 egység sugarú kör területe: 28.274333882308138
4 egység sugarú kör területe: 50.26548245743669
5 egység sugarú kör területe: 78.53981633974483
6 egység sugarú kör területe: 113.09733552923255
7 egység sugarú kör területe: 153.93804002589985
8 egység sugarú kör területe: 201.06192982974676
9 egység sugarú kör területe: 254.46900494077323
10 egység sugarú kör területe: 314.1592653589793
Körterületek összege: 1209.51317163207051209.5131716320705

1 egység sugarú kör területe: 3.141592653589793
2 egység sugarú kör területe: 12.566370614359172
3 egység sugarú kör területe: 28.274333882308138
4 egység sugarú kör területe: 50.26548245743669
5 egység sugarú kör területe: 78.53981633974483
6 egység sugarú kör területe: 113.09733552923255
7 egység sugarú kör területe: 153.93804002589985
8 egység sugarú kör területe: 201.06192982974676
9 egység sugarú kör területe: 254.46900494077323
10 egység sugarú kör területe: 314.1592653589793
Körterületek átlaga: 120.95131716320705120.95131716320705

 

Ne felejtsük el pontosan megalkotni és beállítani a fenti osztályok forráskódjait! A hibamentes futtatáshoz az alábbi szerkezetet kell kialakítanunk a projekt src mappájában:

 

www.informatika-programozas.hu - Interfész