#include <iostream>
#include <string>
using namespace std;
/*
CÉL
----
Ugyanabból az alaposztályból (Eszkoz) háromféle módon származtatunk:
- public
- protected
- private
Az Eszkoz három láthatósági szintet tartalmaz:
- PRIVATE: csak az Eszkoz fér hozzá (pl. szeriaszam) -> közvetlenül SEHOL másutt nem látszik
- PROTECTED: az Eszkoz és a belőle származott osztályok érik el (pl. gyartoKod)
- PUBLIC: mindenki látja (pl. nev, suly, publikus metódusok)
ÉLETSZERŰ SZTORI
----------------
Egy műhely eszközleltára:
- A "szeriaszam" (private) a gyár titka, csak ellenőrzött módon kérdezhető le (getter).
- A "gyartoKod" (protected) belső kód, amit a szerviz/leszármazottak ismerhetnek, de a külvilág nem.
- A "nev" és "suly" (public) katalógusadatok, bárki láthatja.
MIÉRT ÉRDEMES KÜLÖNBÖZŐ ÖRÖKLÉST VÁLASZTANI?
--------------------------------------------
- PUBLIC öröklés: a külvilág is "Eszkoz"-ként használhatja az objektumot (katalógus).
- PROTECTED öröklés: csak a cég/származottak látnak rá "Eszkoz"-ként (belső eszköz, nem publikus API).
- PRIVATE öröklés: az "Eszkoz" csak építőelem (implementációs részlet), kívülről nem látszik az "Eszkoz" arculat.
*/
// ===== Alaposztály (private + protected + public tagokkal) =====
class Eszkoz {
private:
string szeriaszam; // PRIVATE -> csak az Eszkoz éri el közvetlenül
protected:
string gyartoKod; // PROTECTED -> leszármazottak ELÉRIK, de a külvilág nem
// (Tipikusan belső cikkszám, szervizkód, amivel a műhely dolgozik.)
public:
string nev; // PUBLIC -> külvilág is látja (katalógusadat)
double suly; // PUBLIC
Eszkoz(string n = "Ismeretlen", double s = 0.0, string sz = "N/A", string gy = "GY-0000")
: szeriaszam(sz), gyartoKod(gy), nev(n), suly(s) {}
void kiirPublic() const {
cout << "[Eszkoz] Nev: " << nev << ", Súly: " << suly << " kg" << endl;
}
// A private szeriaszam csak kontrolláltan adható ki:
string getSzeriaszam() const { return szeriaszam; }
protected:
// A protected gyártókódot NEM szeretnénk a külvilágnak mutatni -> protected getter.
string getGyartoKod() const { return gyartoKod; }
};
// ===== PUBLIC öröklés =====
// A katalógusban megjelenő általános eszköz.
// - Az Eszkoz PUBLIC tagjai továbbra is PUBLIC-ként látszanak kívülről (nev, suly, kiirPublic).
// - A PROTECTED tag (gyartoKod) itt is elérhető A LESZÁRMAZOTTBÓL, de a külvilág még mindig nem látja.
class AltalanosEszkoz : public Eszkoz {
public:
AltalanosEszkoz(string n, double s, string sz, string gy)
: Eszkoz(n, s, sz, gy) {}
void mutat() {
// Itt MINDENT, ami public/protected, elérünk (kivéve a private szeriaszamot, azt csak getteren át):
cout << "[Általános] " << nev << " (" << suly << " kg)"
<< ", Gyártókód (belső): " << getGyartoKod()
<< ", Szériaszám (getterrel): " << getSzeriaszam() << endl;
}
};
// ===== PROTECTED öröklés =====
// Belső használatra szánt eszköz. Kívülről NEM "Eszkoz" többé: az alaposztály public tagjai PROTECTED-dé válnak.
// - A külvilág nem tudja hívni a kiirPublic()-ot, sem látni a nev/suly mezőt.
// - A leszármazott viszont belülről hozzáfér a public/protected alap-tartalomhoz (nev, suly, gyartoKod).
class BelsoHasznalat : protected Eszkoz {
public:
BelsoHasznalat(string n, double s, string sz, string gy)
: Eszkoz(n, s, sz, gy) {}
void belsoInfo() {
// Belülről elérhető: nev, suly (eredetileg public), gyartoKod (protected), szeriaszam nem (private):
cout << "[Belső] " << nev << " (" << suly << " kg)"
<< ", Gyártókód: " << getGyartoKod()
<< ", Szériaszám (getterrel): " << getSzeriaszam() << endl;
}
// (Ha szeretnénk, készíthetünk publikus wrapper metódusokat, de az Eszkoz "arcát" nem visszük ki külső API-ba.)
};
// ===== PRIVATE öröklés =====
// Titkos fejlesztés. Kívülről SEMMI sem látszik az "Eszkoz"-ból: a public/protected alap-tagok is PRIVATE-té válnak.
// - A külvilág számára NEM létezik, hogy ez "Eszkoz" lenne (nem hívható rajta kiirPublic, nem látszik nev/suly).
// - A leszármazott belül továbbra is használhatja a public/protected alap-tartalmat.
class TitkosFejlesztes : private Eszkoz {
public:
TitkosFejlesztes(string n, double s, string sz, string gy)
: Eszkoz(n, s, sz, gy) {}
void riport() {
cout << "[Titkos] " << nev
<< ", Gyártókód: " << getGyartoKod()
<< ", Szériaszám (getterrel): " << getSzeriaszam() << endl;
}
};
// ===== Virtual / polimorfizmus =====
// Absztrakt ősosztály, amely meghatározza az összes alakzat közös interfészét.
// Minden leszármazottnak kötelező lesz saját terület() függvényt írnia.
class Alakzat {
public:
// Tiszta virtuális függvény = nincs megvalósítása itt,
// így az osztály nem példányosítható (absztrakt marad).
// A leszármazottak saját képletet adnak majd a terület számítására.
virtual double terulet() const = 0;
// Virtuális destruktor: polimorf használatnál fontos,
// hogy a megfelelő leszármazott destruktora fusson le delete-kor.
virtual ~Alakzat() {}
};
// Konkrét osztály: kör
class Kor : public Alakzat {
double r; // Sugár
public:
// Konstruktor: sugár beállítása
Kor(double r) : r(r) {}
// A kör területe képlettel: π * r²
double terulet() const override { return 3.1416 * r * r; }
};
// Konkrét osztály: négyzet
class Negyzet : public Alakzat {
double a; // Oldalhossz
public:
// Konstruktor: oldalhossz beállítása
Negyzet(double a) : a(a) {}
// A négyzet területe képlettel: a²
double terulet() const override { return a * a; }
};
//GYORSGUIDE – HOZZÁFÉRÉS ÖSSZEFOGLALÓ
//------------------------------------
//LEGEND: K = kívülről (main-ből) elérhető? I = osztályon belül (leszármazott kódjából) elérhető?
//
// K I
//PUBLIC öröklés:
// Eszkoz::public -> public ✓ ✓
// Eszkoz::protected -> protected × ✓
// Eszkoz::private -> private × ×
//
//PROTECTED öröklés:
// Eszkoz::public -> protected × ✓
// Eszkoz::protected -> protected × ✓
// Eszkoz::private -> private × ×
//
//PRIVATE öröklés:
// Eszkoz::public -> private × ✓
// Eszkoz::protected -> private × ✓
// Eszkoz::private -> private × ×