2014. szeptember 26., péntek

Tovább az OO elvek mentén - Absztrakció, általánosítás, származtatás

Úgy tűnik hogy ez a Haromszog osztály nem lesz soha igazán objektum-orientált... Már egyszer újraszerveztük és még mindig nem az igazi. De mi is ennek az oka, hol rontottuk el?

Az objektum-orientált programozás alapelveit már tárgyaltam, most nézzük meg hogy hogyan is kell nekiállni egy OO programnak. Először is el kell gondolkodni a problémán és a szükséges mértékig (meg egy picit azon túl) általánosítani kell.
Megcsináltuk a Haromszog osztályunkat, aminél elkövettük azt a hibát, hogy egyből belefogtunk a kódolásba és nem igazán gondoltuk át, hogy mit is szeretnénk. Most ezért tervezzük újra az egész programot, ami két háromszögről megállapítja melyiknek nagyobb a kerülete.

A háromszög az objektum amivel dolgozunk ezt próbáljuk általánosítani. Ennek kapcsán általánosan mondhatjuk hogy a háromszögek azok síkidomok. A síkidomoknak van kerülete és területe. Többféle síkidom létezik (vannak pl a négyszögek, kör stb), ráadásul a háromszögeknek is vannak speciális esetei (derékszögű, egyenlő oldalú stb...). Miután ezt végiggondoltuk máris egy hierarchia jelenik meg a képzeletünkben aminek a csúcsán ott van a síkidom és abból származik az összes egyéb más előbb említett objektum.
Javában pontosan ezt a hierarchiát kell megcsinálnunk és a fa ágain haladva egyre specializáltabbá tennünk, kibővíteni, felülírni az egyes újabb szintek tulajdonságait, metódusait. A nyelv támogatja is ezt a fajta megvalósítást.

Definiáljuk először a Sikidom osztályt. Az osztályból példányosítani nem fogunk, csak általánosan fogalmazzuk meg benne ami egy síkidomra jellemző. Az ilyen osztályokat, amikből hiányoznak a konkrétumok absztrakt osztályoknak nevezzük és az abstract kulcsszóval definiáljuk. Ezek az osztályok nem példányosíthatók, csak a leszármazottakban lehet örököltetni a saját metódusait, amit majd ott fog kelleni konkretizálni. A példában a kerület és terület számítás minden síkidomra értelmezett, de hogy konkrétan hogyan kell kiszámolni azt majd az adott síkidom definiálásakor adjuk meg.

public abstract class Sikidom {
   public abstract double kerulet();
   public abstract double terulet();
}

Ezzel megadtuk a hierarchia csúcsán lévő absztrakt osztályt, amiből tovább szervezzük, specializáljuk a síkidomokat.

Hozzuk létre a háromszögek osztályt származtatással. Ez már nem absztrakt osztály lesz, mert pontosan fogjuk tudni az adatait és a metódusait is ki tudjuk fejteni. Tudni kell még azt, hogy az absztraktnak definiált metódusokat a leszármazottakban definiálni kell, különben a fordító hibát fog jelezni!

public class Haromszog extends Sikidom {
   private double a, b, c;
   
   public Haromszog(int a, int b, int c){
      this.a = a;
      this.b = b;
      this.c = c;
    }

   // absztrakt metódusok definiálása
   public double kerulet(){
      return a+b+c;
   }

   public double terulet(){
      //Heron képlet alapján a terület kiszámítása
      double s = this.kerulet()/2
      return Math.sqrt(s*(s-a)*(s-b)*(s-c)); 
   }
}

Megjegyzés: a feladat matematikai megoldásának ismerete nem programozói feladat, azaz nem jó vagy rossz programozó aki nem tudja hogy esetünkben hogyan kell kiszámítani a háromszög területét (valós helyzetben nem a programozónak kell tudni hogy hogyan működnek a pénzügyik/könyvelési folyamatok amikhez éppen szoftvert készít). Ezeket a dolgokat a rendszer tervezésekor a rendszerszervezőnek kell feltárnia. Természetesen alapvető tájékozottság elengedhetetlen, főként az algoritmusok, matematikai lehetőségek terén.

Az osztályhierarchiát tovább lehet bővíteni a többi síkidom definíciójával (kör, téglalap, négyzet stb):

public class Kor extends Sikidom{
   private double r;

   //konstruktor
   public Kor(double r){
      this.r = r;
   }

   // absztrakt metódusok definiálása
   public double kerulet(){
      return 2*r*Math.PI;
   }

   public double terulet(){
      return 4*r*r*Math.PI; 
   }
}


Az így elkészített osztályhierarchia már sokkal inkább átgondolt és logikus, a való világ egy részének absztrakciója, amit objektum-orientált szemlélettel terveztünk meg és implementáltuk Java programként.

A következő cikkben egy picit átgondoljuk hogy mi akkor a teendő, ha valami probléma van az adatokkal, hogyan tudjuk kezelni az ilyen eseteket.

1 megjegyzés:

  1. Szia!
    Most tanulom a java-t de ezt nem értem itt, miért van értelme itt ennek, ha a Sikidom semmit nem ad át az alatta lévő osztályoknak (változók), sőt még a függvények is át lesznek írva.
    Bocs ha nem jól fejeztem ki magam, nem kötözködni akarok, csak megérteni az öröklődést, mert ahogy én kitaláltam nem működik. (

    VálaszTörlés