Öröklődés 2..

Slides:



Advertisements
Hasonló előadás
Osztály leszármaztatás
Advertisements

Krizsán Zoltán iit 1.1.  Aszinkron történésről értesítés egy vagy több objektum számára.  Delegátumok segítségével valósítja meg a C#.  event típus,
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
AZ OOP ALAPJAI.
Jt Java Feltételek, logikai kifejezések. jt 2 Logikai operátorok Logikai kifejezésekre alkalmazhatók a következő műveletek: 1. nem! 2. és&ill.&& 3. kizáró.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
© Kozsik Tamás Tömbök, kollekciók és egyéb alaposztályok.
© Kozsik Tamás Beágyazott osztályok A blokkstrukturáltság támogatása –Eddig: egymásba ágyazható blokk utasítások Osztálydefiníciók is egymásba.
Objektum-elvű programozás (OOP)
Csala Péter ANDN #4. 2 Tartalom  C# - ban előre definiált típusok  Változók  Változókkal műveletek  Elágazás  Ciklus.
Öröklődés Polimorfizmus Csomagok Absztrakt osztályok, interfészek
Fájlkezelés, IO Kivételkezelés Belső osztályok
Osztályok Garbage collection.  általában minden osztálynak vannak adattagjai és/vagy metódusai ◦ adattagok megadása:  [láthatóság] [static] [final]
Abstract osztályok és interface-ek Beolvasás és kiíratás 7. gyakorlat.
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás II. 5. Gyakorlat Öröklődés, virtuális függvények,
Programozás II. 3. Gyakorlat C++ alapok.
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás II. 6. Gyakorlat const, static, dinamikus 2D.
Tömbök ismétlés Osztályok Java-ban Garbage collection
Az objektum-orientált tervezési alapelvek kritikai vizsgálata
A Java programozási nyelvSoós Sándor 1/17 Java programozási nyelv 4. rész – Osztályok II. Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai.
A Java programozási nyelvSoós Sándor 1/16 Java programozási nyelv 6. rész – Java a gyakorlatban Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai.
Java programozási nyelv 3. rész – Osztályok I.
A C++ programozási nyelvSoós Sándor 1/10 C++ programozási nyelv Gyakorlat - 5. hét Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet.
A C++ programozási nyelvSoós Sándor 1/15 C++ programozási nyelv Gyakorlat hét Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet.
Java programozási nyelv 5. rész – Osztályok III.
C# tagfüggvények.
C# tagfüggvények.
Csomagok.
Annotációk a Java 5 nyelvben Kozsik Tamás. Annotációk Módosítószavak bővítése A programszöveg elemeihez rendelhetők –Csomagokhoz, típusokhoz, metódusokhoz,
© Kozsik Tamás Csomagok. © Kozsik Tamás A program tagolása Típusdefiníciók (osztályok, interfészek) Metódusok Blokk utasítások Csomagok.
OOP ÖRÖKLŐDÉS, INTERFÉSZ
A JAVA TECHNOLÓGIA LÉNYEGE Többlépcsős fordítás A JAVA TECHNOLÓGIA LÉNYEGE Platformfüggetlenség.
A Java jellemzői Hordozható, platformfüggetlen forráskód és bájtkód szinten forráskód és bájtkód szinten Tisztán objektumorientált csak osztályok, illetve.
Kivételkezelés.
P ROGRAMOZÁS C# - BAN Kivételkezelés. P ÉLDA I. Nullával való osztás miatt kapjuk a hibaüzenetet.
Szoftvertechnológia alapjai Java előadások Förhécz András, doktorandusz tárgy honlap:
1. Gyakorlat - Alapok 1. Írjon konzolprogramot, amely kiírja a “Hello ELTE” üzenetet! Használja a System.out.println() -t! 2. Írjon konzolprogramot, amely.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
Hernyák Zoltán Programozási Nyelvek II.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
Hernyák Zoltán Programozási Nyelvek II.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
Javascript Microsoft által készített kiegészítése Statikus típusosság Nagy projektek Windows 8 fejlesztésénél WinRT egy részét ebben írták Nyílt forráskódú,
Java programozási nyelv Metódusok
Java programozási nyelv Adatbekérés konzolról
Bevezetés Amiről ma szó lesz… Miért D? Mert a fejlesztők úgy látták, hogy a C++-on van még mit javítani. Mert a programozók a nyelvnek általában elszigetelt.
Generics Krizsán Zoltán. Bemutató A.NET 2.0 verziótól. A.NET 2.0 verziótól. Típusparaméter Típusparaméter Más nyelvben ez a template (sablon). Más nyelvben.
Programozás III KOLLEKCIÓK.
1 Objektum orientált programozás Öröklődés: többszörös öröklődés, konstruktorok, destruktorok, overloading Nagy Szilvia.
OOP ÖRÖKLŐDÉS, INTERFÉSZ
Programozás III OOP ALAPOK.
Programozás III OOP ÖRÖKLŐDÉS.
Programozás III KOLLEKCIÓK.
Ficsor Lajos CPP2 / 1 Származtatási mechanizmus a C++ nyelvben Ficsor Lajos Miskolci Egyetem Általános Informatikai Tanszék.
1Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Programozás I. 5. gyakorlat.
5. előadás Parametrikus polimorfizmus. Generikus programozás. Az Ada sablonok.
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás I. 7. gyakorlat.
Objektum orientált programozás 4. Mutatók, típusok és struktúrák Nagy Szilvia.
1Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Programozás I. 6. gyakorlat.
1Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Programozás I. 4. gyakorlat.
TÁMOP /1-2F JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam Osztályok, objektumok definiálása és alkalmazása. Saját.
Krizsán Zoltán, iit C# osztályok 2 Adattagok  Osztály hatáskörben definiált változó.  Formája: [attribútum] [módosító] típus azonosító [=kezdő érték][,
Hernyák Zoltán Programozási Nyelvek II.
JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam
JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam
Előadás másolata:

Öröklődés 2.

Ismétlés – 1-3. példa //Inicializálatlan változó használata -> FORDÍTÁSI HIBA! Alkalmazott a; a.fizetéstEmel(20); //null referencián keresztül műveletvégzés -> NullPointerException Alkalmazott a = null; a.fizetéstEmel(20000); // objektum példányosítása new Alkalmazott(); // objektum példányosítása + változóhoz rendelése Alkalmazott a = new Alkalmazott(); // vagy Alkalmazott a; … a = new Alkalmazott();

Ismétlés – 4. példa // referencia állítása objektumra Alkalmazott a = new Alkalmazott(); Alkalmazott b = a; // Nem készül másolat!!! b.fizetéstEmel(10000); System.out.println(a.fizetés); // 10000

Ismétlés – 5. példa class Alkalmazott { ... // információ elrejtése, invariáns megőrzése private int fizetés; // a fizetést kívülről ne lehessen közvetlenül módosítani, mert // akkor az évesfizetés elromlik! private int évesFizetés; // az évesFizetést kívülről sehogyan se lehessen módosítani // a fizetés megváltozásával szükségszerűen az ő értéke is változzon public int getFizetés() { return fizetés; } public int getÉvesFizetés() { return évesFizetés; public void fizetéstBeállít(int új) { fizetés = új; évesFizetés = 12*fizetés;

Ismétlés – 6. példa class Alkalmazott { ... // osztályszintű változó + metódus static int nyugdíjKorhatár = 60; public static void nyugdíjKorhatártEmel( int mennyivel ) { nyugdíjKorhatár+=mennyivel; } class Program { // hivatkozás osztályszintű változóra Alkalmazott a = new Alkalmazott(); System.out.println(a.nyugdíjKorhatár); // warning -> osztályon keresztül illik elérni System.out.println(Alkalmazott.nyugdíjKorhatár);

Ismétlés – 7. példa – túlterhelés metódus szignatúrája = név + paraméterek típusának sorozata túlterheléshez szükségesek a különböző szignatúrák class Alkalmazott { ... // túlterhelés public void fizetéstEmel() { fizetés += 10000; } void fizetéstEmel( int mennyivel ) { fizetés += mennyivel;

Ismétlés – 8. példa – konstruktorok class Alkalmazott { ... // konstruktorok private int évesFizetés; public Alkalmazott(String név, int fizetés) { this.név = név; this.fizetés = fizetés; évesFizetés = 12*fizetés; } // Mivel írtunk konstruktort, nem jön létre public Alkalmazott() {} // Másik konstrukor meghívása : this(...) // Csak a konstruktor első sorában lehet! public Alkalmazott(String név) { this(név,100000);

Öröklődés során mit tehetünk a leszármazott osztályokban? Az öröklött adattagokat közvetlenül használhatjuk. Deklarálhatunk azonos nevű adattagot, mint ami már az ősosztályban is szerepelt. Ezt nevezzük elfedésnek. Adattagok elfedése rossz programozási módszerre vall, használata nem ajánlott. Deklarálhatunk olyan adattagokat, amelyek az ősosztályban nem szerepelnek. Az öröklött metódusokat közvetlenül használhatjuk. Írhatunk új példánymetódusokat ugyanolyan névvel és szignatúrával, mint az ősosztályban. Ezt nevezzük felüldefiniálásnak. (ld. részletesen később) Írhatunk új osztálymetódusokat ugyanolyan névvel és szignatúrával, mint az ősosztályban. Ezt nevezzük elfedésnek. Deklarálhatunk új metódusokat, amelyek nem szerepelnek az ősosztályban. Írhatunk konstruktort, ami meghívja az ősosztály valamelyik konstruktorát (implicit vagy explicit módon).

Konstruktorhívások a Javában Hozzunk létre egy új csomagot, majd tegyük bele a már megírt Alkalmazott.java osztályt. Hozzuk létre a Főnök osztályt az Alkalmazott osztály leszármazottjaként! Az új adattagok legyenek: public class Főnök extends Alkalmazott { private Alkalmazott[] beosztottak; private static final int maxBeosztott = 10; private int beosztottakSzáma; } Fordítási hibát kapunk! Miért???

Konstruktorhívások – a fordítási hiba oka A Főnök osztályban nem írtunk konstruktort, ezért implicit módon létrejön egy üres törzsű. Ha egy konstruktor nem hív meg másik konstruktort (ez csak az első sorában tehető meg), akkor implicit módon létrejön egy super() hívás az első sorban. Ez azt jelenti, hogy az Alkalmazott osztály üres konstruktora akar végrehajtódni. Mivel (az Alkalmazott osztályban írtunk konstruktort, implicit módon nem jön létre üres törzsű) + (nem írtunk üres törzsű konstruktort) = az Alkalmazott osztálynak nincs üres törzsű konstruktora. Ezek után a fordítási hiba nyilvánvaló.

Konstruktorhívások – Hogyan javítsuk a hibát? Lehetőleg ne az Alkalmazott osztályban írjunk üres konstruktort! (ezt sok esetben nem is tehetjük meg, hiszen már más által megírt osztályból származtatunk.) FELADAT: Írjunk a Főnök osztályban egy egy- és egy kétparaméteres konstruktort! Az egyik hívja meg az Alkalmazott osztály valamelyik konstruktorát, a másik pedig az egyiket! Gondoljuk át, hogy melyik legyen az egyik, és melyik a másik? Írjunk egy újBeosztott metódust is, amely a paraméterként kapott alkalmazottat felveszi a beosztottak közé, ha van még hely, és igazzal tér vissza. Ha már nincs hely, akkor térjen vissza hamissal.

Konstruktorhívások public Főnök(String név, int fizetés) { super(név,fizetés); beosztottak = new Alkalmazott[maxBeosztott]; actBeosztott = 0; } public Főnök(String név) { this(név,200000); boolean újBeosztott(Alkalmazott a) { if (beosztottakSzáma<maxBeosztott) { beosztottak[beosztottakSzáma] = a; beosztottakSzáma++; return true; else { return false;

Konstruktorhívások – a lefutási sorrend A főrogramban a Főnök f = new Főnök("Feri"); sor hatására milyen sorrendben hívódnak meg és futnak le a különböző konstruktorok? Meghívódik a Főnök osztály egyparaméteres konstruktora. Mivel az első sorában hívunk meg másik konstruktort, az fog végrehajtódni. Tehát elkezdődik a Főnök osztály kétparaméteres konstruktorának a végrehajtása. A JRE újra megvizsgálja, hogy ez a konstruktor hív-e meg másik konstruktort. A válasz igen, mégpedig az Alkalmazott osztály kétparaméteres konstruktorát. Így ennek a végrehajtása kezdődik meg. Meghívódik az Object osztály paraméter nélküli konstruktora!!! Miért??? Befejeződik az Alkalmazott osztály kétparaméteres konstruktorának végrehajtása. Befejeződik a Főnök osztály kétparaméteres konstruktorának végrehajtása. Befejeződik a Főnök osztály egyparaméteres konstruktorának végrehajtása .

Altípus fogalma (informálisan) Egy A típus altípusa egy B típusnak, ha minden olyan helyzetben, ahol B típusú objektum használható, A típusú objektum is használható. Ez a tulajdonság teljesül a Java öröklődése esetén. Miért? Megjegyzés: A múlt órán csak az öröklődés másik fő előnyét, a kód-újrafelhasználást használtuk ki.

Polimorfizmus (altípusos polimorfizmus) Altípusos polimorfizmusnak azt a jelenséget nevezzük, hogy egy rögzített típusú változó (pl. Alkalmazott) hivatkozhat több különböző típusú objektumra (pl. Alkalmazott, Főnök). Emellett a műveletek is „több típussal rendelkezhetnek”: az Alkalmazott osztály műveletei meghívhatók Főnök típusú objektumokra is.

Polimorfizmus Az Alkalmazott osztály műveletei meghívhatók Főnök típusú objektumokra is: Főnök f = new Főnök("Feri"); int i = f.getFizetés(); Egy Alkalmazott típusú referenciának értékül adható egy Főnök típusú objektum: Alkalmazott a = new Főnök("Feri"); Egy Alkalmazott formális paraméterrel rendelkező metódus meghívható Főnök típusú aktuális paraméterrel: Alkalmazott a = new Alkalmazott("Pisti"); boolean b = a.többetKeresMint(f);

Statikus és dinamikus típus Ha egy Alkalmazott típusúként deklarált referenciaváltozó egy Főnök típusú objektumra vonatkozik, akkor mi is az igazi típusa a változónak? Statikus típus: a deklarációnál megadott típus Dinamikus típus: a változó által mutatott objektum tényleges típusa A dinamikus típus vagy maga a statikus típus, vagy egy leszármazottja. (különben fordítási hibát kapunk) A statikus típus állandó, a dinamikus típus változhat a program futása során.

Statikus és dinamikus típus -- példák Alkalmazott a = new Alkalmazott(„Pisti"); //statikus=dinamikus=Alkalmazott Főnök b = new Főnök("Feri"); //statikus típus=dinamikus típus=Főnök Alkalmazott c = new Főnök("Zoli"); //statikus=Alkalmazott, dinamikus=Főnök a = c; //st. típus=Alkalmazott, din. típus=Főnök a = new Alkalmazott("Tomi"); //statikus típus=dinamikus típus=Alkalmazott a = b; //st. típus=Alkalmazott, din. típus=Főnök Object o = new Alkalmazott("Józsi"); o.fizetéstEmel(20000); // fordítási hiba: Object-nek nincs ilyen metódusa Alkalmazott a = o; // fordítási hiba: o nem feltétlenül Alkalmazott

Statikus és dinamikus típus szerepe A statikus típus dönti el azt, hogy milyen műveletet végezhetők a referenciaváltozón keresztül. A dinamikus típus dönti el azt, hogy a végrehajtandó metódusnak melyik törzse fusson le. Ld. dinamikus kötés

Felüldefiniálás A gyermek osztályban sokszor azt szeretnénk, ha másképp tudnánk bizonyos eseményekre reagálni, mint ahogy a szülő reagál. Például a múlt órai Autó, Taxi osztályokban a költséget számító metódus és a toString() esetén. Akkor beszélünk felüldefiniálásról, ha: Az ősosztálybeli és a leszármazott osztálybeli metódus szignatúrája megegyezik. A visszatérési típus megegyezik. (Java 5.0-tól kovariánsan változhat) A hozzáférési kategória nem szűkülhet a leszármazott osztályban. A kiváltható kivételek halmaza nem bővülhet.

Dinamikus kötés A múlt órán tulajdonképpen az öröklődésnek „csak” a kód-újrafelhasználó előnyét használtuk ki, az altípusképző előnyét nem. (Hiszen ha írtunk volna copy-paste technikával egy sima Taxi osztályt öröklődés nélkül, akkor a főprogam ugyanúgy működne.) Az öröklődés altípusképző előnyét a dinamikus kötés segítségével lehet kihasználni. A dinamikus kötés bemutatásához szükség van egy, a leszármazott osztályban felüldefiniált metódusra.

Dinamikus kötés FELADAT Definiáljuk felül a pótlék() metódust a Főnök osztályban! Adja vissza az Alkalmazott-nak kiszámított pótlékot, és még beosztottanként 20000 forintot! Definiáljuk felül a toString() metódust is!

Dinamikus kötés Mit csinál a főprogram? Alkalmazott a = new Alkalmazott("Józsi"); Főnök f = new Főnök("Feri"); f.újBeosztott(a); int i = a.pótlék(); int j = f.pótlék(); a=f; int k = a.pótlék(); // DINAMIKUS KÖTÉS! int l = f.teljesFizetés(); // DINAMIKUS KÖTÉS A METÓDUS TÖRZSÉN BELÜL IS!

Dinamikus kötés – megjegyzések Nagyon fontos, hogy a dinamikus kötéshez elengedhetetlen a felüldefiniált metódus! Mindig győződjünk meg róla, hogy tényleg felüldefiniáltuk-e a kívánt metódust, mert ha véletlenül túlterheltük, nem kapunk fordítási hibát, de futási időben nem az fog történni, amit várunk!

Dinamikus kötés – helytelen példa int pótlék(int i) { // a Főnök osztályban írjuk meg! return super.pótlék()+i; } Tegyük fel, hogy még nem definiáltuk felül az Alkalmazott osztály pótlék metódusát. Úgy gondolkodhatunk (helytelenül!!!), hogy a Főnök osztályban úgy számoljunk pótlékot, hogy az Alkalmazott szerinti pótlékhoz adjuk hozzá a paraméterként kapott számot. Ez nem felüldefiniálás, hanem túlterhelés! Alkalmazott a = new Alkalmazott("Józsi"); Főnök f = new Főnök("Feri"); int i = a.pótlék(); int j = f.pótlék(); int l = a.pótlék(10000); // fordítási hiba int n = f.pótlék(10000); // OK a=f; int k = a.pótlék(); // alkalmazott szerinti pótlék int m = a.pótlék(10000); // fordítási hiba

Statikus metódusok és az elfedés Statikus metódusokat nem lehet felüldefiniálni! Ebből következik, hogy dinamikus kötés sincs statikus metódusoknál! Abban az esetben, amikor egy leszármazott osztályban egy azonos szignatúrájú és visszatérési értékű metódust írunk, mint ami van az ősosztályban, akkor nem felüldefiniálásról, hanem elfedésről beszélünk. Ez azt jelenti, hogy statikus típus alapján dől el, hogy melyik törzs hajtódik végre.

Objektumok konverziói A leszármazott osztályba tartozó objektum automatikusan konvertálódik ősosztálybeli objektummá. Ezt nevezik alulról felfelé történő konverziónak. Alkalmazott a = new Főnök(); Ősosztálybeli objektumot csak explicit módon tudunk leszármazott osztálybeli objektummá konvertálni. Alkalmazott a = new Főnök(); Főnök f = (Főnök)a; Ezzel az a probléma, hogy fordítási időben nem derül ki, hogy tényleg Főnök-e a konvertálni kívánt Alkalmazott. Ha ez nem teljesül, akkor futási időben ClassCastException váltódik ki. Ha ezt nem akarjuk, akkor ellenőrzést is végezhetünk az instanceof operátor segítségével. if (a instanceof Főnök) { Főnök f2 = (Főnök) a; ... }

Feladat Egy vállalatnál alkalmazottak dolgoznak. Közülük néhányan főnökök is. A főnököknek legyenek alkalmazottaik! Legyen olyan sima alkalmazott és főnök is, akinek van nyelvvizsgája! A vállalat alkalmazottainak adatait tömbben tároljuk! Mi legyen a tömb objektumra mutató referenciaváltozó statikus típusa? (Object, Alkalmazott vagy Főnök?) Számítsuk ki az összes alkalmazott (ebbe a főnökök is beletartoznak) pótlékokkal együtt számított átlagos teljes fizetését! Emellett számítsuk ki külön a főnökök pótlékokkal együtt számított átlagos teljes fizetését!

Házi feladat Készítsd el a Pont osztályt! Tulajdonságok: x és y koordináta, művelet: eltolás dx és dy értékekkel. Az adattagokat explicit módon inicializáld 0-ra! Készítsd el a Kör osztályt! Tulajdonságok: középpont (Pont) és sugár (double), műveletek: eltol és nagyít. (a középpontot kell eltolni, nagyításnál a sugarat szorozni) A Kör osztályban vezess be egy új attribútumot, a területet tartsuk benne nyilván! Írd meg a sugaratBeállít műveletet! Használd a Math.PI értéket! Az attribútumok legyenek privátok, a műveletek publikusak! Készíts publikus lekérdező műveleteket a sugárhoz és a területhez! A Pont és a Kör osztályokhoz készítsd el a távolság() metódust, mely megadja az objektum távolságát egy, a paraméterként átadott Pont objektumtól! A Kör osztályban definiálj példánymetódust, mely a paraméterként átadott pont objektumot a kör középpontjába állítja: public void középpontba(Pont p)! A Kör osztályhoz írj illeszkedik() műveletet, mely eldönti, hogy a paraméterként megadott Pont objektum illeszkedik-e a körvonalra -- egy adott tűréshatáron belül. A tűréshatár értéke a Kör osztály jellemzője. A Kör osztály sugaratBeállít metódusának formális paramétere legyen ugyanúgy elnevezve, mint a sugár attribútum!

Házi feladat (folytatás) Készíts középpontos tükrözést végző műveleteket a Pont és a Kör osztályokban. A műveleteket meg lehessen hívni Pont objektummal is és két koordinátával (cx,cy) is! Valósítsd meg a középpontos tükrözés műveleteket úgy, hogy egymást hívják! Készítsd el a SzínesPont osztályt a Pont osztály leszármazottjaként! Új tulajdonság: szín. Új műveletek: szín beállítása és lekérdezése. A szín attribútum legyen privát! A Pont és a Kör osztályokhoz készíts konstruktorokat! A Pont osztályhoz csak egyet, aminek a koordinátákat lehet átadni. A Kör osztályhoz hármat: az elsőnek a sugarat és egy Pont objektumot (ez lesz a középpont), a másodiknak a sugarat és a középpont koordinátáit lehet átadni, a harmadik legyen paraméter nélküli konstruktor. Melyik Kör konstruktor hívhat meg másikat? Miért nem fordul a SzínesPont osztály? Javítsd! Készítsd el a SzínesKör osztályt a Kör osztály leszármazottjaként! Új műveletei: a szín beállítása és lekérdezése. Ne vezess be új adattagot: a színes körök színét a középpontjuk színe határozza meg, amely nem közönséges Pont, hanem SzínesPont! Készíts public String toString() műveletet a Pont és SzínesPont osztályokhoz, mely adatokat szolgáltat az ilyen objektumokról egy String formájában! A Pont osztályban definiáljunk println metódust, mely kiírja a pontot a szabványos kimenetre! (Ehhez az előző feladatban megírt toString metódust használjuk!) Nézzük meg, hogyan működik az örökölt println metódus a SzínesPont objektumokon! Hozz létre egy Program osztályt! Ebben írj statikus main metódust! Hozz létre egy körökből álló 5 elemű tömb objektumot! A legnagyobb területű kör jellemzőit írasd ki a képernyőre! Lehetőleg ne használj explicit konverziót!