Adózó és beteg alkalmazott

Alkalmazottakat (Employee) tartunk nyilván egy polgármesteri hivatalnak készülő nyilvántartási rendszerünkben, amelyet a helyi kórház is használni fog. Az Alkalmazott a Személy osztályból (Person) származnak. A nyilvántartó rendszer két másik rendszerrel van kapcsolatban: az egyik az adóhivatal rendszere, a másik az egészségbiztosításé.

A Személy osztály deklarációja az alábbi:

class Person

{

protected:

      string name;

      int birthYear;

public:

      Person(string name,

            int birthYear):name(name), birthYear(birthYear){}

      void print(){ cout << name << ' ' << birthYear << endl;}

      void setBirthYear(int birthYear){ this->birthYear = birthYear; }

};


Az adóhivatal rendszere az alábbi osztályt adja, amibe nem nyúlhatunk bele, a forrása nincs meg, csak a .h file és a tárgykódú file valamilyen formátumban (.obj, .o, .a, .lib, .dll,.so):

class TaxSystem

{    

      unsigned tax;

public:

      TaxSystem();

      // Ezzel kell adót befizetni

      void payTax(const ITaxPayer& taxPayer);

};

Ennek egy lehetséges implementációja az alábbi (a példa szerint nem áll rendelkezésre, csak binárisan, jelen példában nem akarjuk az összes operációs rendszerre lefordítva odaadni, inkább közöljük):

class TaxSystem

{    

      unsigned tax;

public:

      TaxSystem():tax(0){};

      // Ezzel kell adót befizetni

      void payTax(const ITaxPayer& taxPayer)

      {

            // Húsz százalékot adózik

            tax+=taxPayer.getIncome()*0.2-taxPayer.taxReduction();

      }

};

Ennek az adófizetést végző függvénye az alábbi osztályt várja, amelyet mi is megkapunk:

class ITaxPayer

{

public:

      // Az évi jövedelmet adja vissza

      virtual unsigned getIncome()const=0;

      // Az adókedvezményt adja vissza

      virtual unsigned taxReduction()const=0;

};


Hasonlóan az egészségbiztosítás is rendelkezik egy rendszerrel, a függvények deklarációit .h állományban meg is kapjuk:

class HealthCare

{          

public:

     

      // Megnézi, van-e fedezet egy kezelésre

      static bool isInsuranceForTreatment(IInsured& insured, unsigned amount);

      // Levonja az kezelés költségét a biztosított egyenlegéből

      static void chargeTreatment(IInsured& insured, unsigned amount);

};

Az implementáció nem áll rendelkezésre, csak binárisan, most az egyszerűség kedvéért megadjuk:

class HealthCare

{          

public:

     

      // Megnézi, van-e fedezet egy kezelésre

      static bool isInsuranceForTreatment(IInsured& insured, unsigned amount)

      {

            if(insured.isValidInsurance() && insured.getInsuranceBalance() - amount >=0)

            {

                  return true;

            }

            else

            {

                  return false;

            }

      }

 

      // Le vonja az kezelés költségét a biztosított egyenlegéből

      static void chargeTreatment(IInsured& insured, unsigned amount)

      {

            if(isInsuranceForTreatment(insured,amount))

            {

                  // Hibakezelés

                  assert(0);

            }

            else

            {

                  insured.decreaseIsuranceBalance(amount);

            }

      }

};

Az IInsured osztály szintén rendelkezésre áll:

class IInsured

{

public:

      // Az egészségbiztosítás egyenlegét adja vissz

      virtual unsigned getInsuranceBalance()const=0;

      // Megadja, hogy van-e az illetőnek érvényes biztosítása

      virtual bool isValidInsurance()const=0;

      //

      virtual void decreaseIsuranceBalance(unsigned amount)=0;

};




Azt szeretnénk elérni, hogy az Employee osztály példányait egyszerűen tudjuk adóztatni, vagy ellenőrizni, van-e fedezet az ellátásra, illetve az ellátás költségét levonni a biztosításból.

Erre egy példa:

int main()

{

      Employee emp ("James Bond", 1930,1952);

      emp.salary=200000; // Ennyit keres havonta

      emp.insuranceBalance+=700000; // Ennyi TB-t fizetnek utána, Mr. Bond gyakran kerül kórházba

 

      // Az APEH rendszeréhez kapcsolódunk

      TaxSystem ts;

      // Adót fizetünk

      ts.payTax(emp);

 

      // Mr. Bond kórházba kerül egy lövöldözés után az Aranykéz utcában (Golden Hand c. epizód)

      // Az OEP rendszeréhez kapcsolódik a kórház, megnézi, ki tudja-e fizetni a kezelést

      if(!HealthCare::isInsuranceForTreatment(emp,500000))

      {

            cout << "No money for treatment" << endl;

      }

 

      // A kezelés után levonja a kezelés értékét a biztosításból

      HealthCare::chargeTreatment(emp,500000);

 

}

 



A megoldásért kattints ide!
Amennyiben több, általunk nem befolyásolható rendszerhez kell illeszkednünk, akkor gyakori a többszörös öröklés. Esetünkben szeretnénk, ha az Employee osztály példányait mind ITaxPayerként, mind IInsuredként használhatnánk. Vagyis ezekből is leszármaztatjuk:

class Employee: public Person, public ITaxPayer, public IInsured

{

      int employmentYear;

     

public:

      unsigned salary;

      unsigned insuranceBalance;

      Employee(string name, int birthYear,

            int employmentYear):Person(name, birthYear),

            employmentYear(employmentYear),salary(0), insuranceBalance(0){}

 

      // Saját függvény

      void setEmploymentYear(int employmentYear)

      {

            this->employmentYear = employmentYear;

      }

 

      // A Person virtuális tagfüggvényének felülírása

      void print()

      {

            cout << name << ' ' << birthYear << ' '

                   << employmentYear << endl;

      }

 

      // Az ITaxPayer virtuális tagfüggvényeinek

      virtual unsigned getIncome()const

      {

            // 13. havi és egyéb dolgokat nem veszünk figyelembe

            return salary*12;

      }

 

      // Ezt ki lehetne számolni a példa bonyolításával, ezt nem tesszük,

      // a példában senkinek nem lesz adókedvezménye

      unsigned taxReduction()const

      {

            return 0;

      }

     

      // Az IInsured virtuális tagfüggvényeinek felülírása

      unsigned getInsuranceBalance()const

      {

            return insuranceBalance;

      }

 

      // Egy alkalmazott mindig biztosított

      bool isValidInsurance()const

      {

            return true;

      }

 

     

      void decreaseIsuranceBalance(unsigned amount)

      {

            if(amount <= insuranceBalance)

            {

                  insuranceBalance-=amount;

            }

            else

            {

                  // Hibakezelés

                  assert(0);

            }

      }

 

};

 

Figyeljük meg, hogy implementációt csak a Person osztálytól örökölt, a többi esetben csak tisztán virtuális függvényeket implementált. A csak tisztán virtuális függvényeket tartalmazó osztály neve interfész (innen az I előtag). Vagyis csak egy osztálytól öröklünk implementációt, a többitől csak interfészt, amin keresztül a két másik rendszer hozzáférhet az objektum bizonyos tagfüggvényeihez. Ez követendő példa: maximum egy osztálytól örököljünk implelentációt, a többitől csak interfészt (azt is akkor, ha már kész, általunk nem módosítható komponenshez kell illesztenünk az osztályt)!





2008.02.06. 19:36:15 |  Permalink  |  Hozzászólások száma: 0  |  Tárgyszavak: Többszörös öröklés


Írja meg Ön is véleményét!


Hozzászólásokat csak regisztrált, bejelentkezett felhasználóktól tudunk elfogadni!

Hozzászólások