Oop on. OOP - mikä se on? Olio-ohjelmoinnin perusperiaatteet. Kirjoitus: staattinen tai dynaaminen

Abstraktit tietotyypit

Abstraktien tietotyyppien käsite on avain ohjelmoinnissa. Abstraktio tarkoittaa rajapinnan ja toteutuksen erottamista ja riippumatonta tarkastelua.

Katsotaanpa esimerkkiä. Me kaikki katsomme televisio-ohjelmia. Kutsutaan televisiota moduuliksi tai esineeksi. Tällä objektilla on käyttöliittymä käyttäjän kanssa eli säätimet (painikesarja), kuvan ja äänen toisto. Mitä edistyneempi käyttöliittymä, sitä mukavampi televisio on käyttää. Vaihdamme ohjelmaa painamalla tiettyjä painikkeita, emmekä samalla ajattele televisiossa tapahtuvia fyysisiä prosesseja. Asiantuntijat tietävät tämän. Kun valitsemme television, olemme kiinnostuneita sen hinnasta ja toimintaparametreja, eli kuvan, äänen jne. laatu. Emme kuitenkaan ole kiinnostuneita siitä, mitä sisällä on. Toisin sanoen palataan objektin (moduulin) ominaisuuksiin, jotka ovat käyttöliittymä ja toteutus. Abstraktion päätarkoitus ohjelmoinnissa on juuri erottaa käyttöliittymä toteutuksesta.

Palataanpa esimerkkiimme. Oletetaan, että joku tutkittava on varma, että hän tuntee television rakenteen hyvin. Hän poistaa kannen ja alkaa "parantaa" sitä. Vaikka tämä joskus johtaakin välillisiin (paikallisiin) onnistumisihin, lopputulos on lähes aina negatiivinen. Siksi tällaiset toimet on kiellettävä. Ohjelmoinnissa tätä tukevat mekanismit pääsyn estoon tai sisäisten komponenttien piilottamiseen. Jokaisella objektilla (moduulilla) on oikeus hallita "omaa omaisuuttaan" eli näitä toimintoja ja operaatioita. Tämän periaatteen huomiotta jättäminen loukkaa järjestelmän vakautta ja johtaa usein sen täydelliseen tuhoutumiseen. Abstraktioperiaate edellyttää piilomekanismien käyttöä, jotka estävät sisäisten komponenttien tahallisen tai tahattoman muuttamisen.

Datan abstraktio edellyttää määrittelyä ja harkintaa abstrakteja tietotyyppejä(ATD) tai, mikä on sama, uudentyyppisiä käyttäjän syöttämiä tietoja.

Abstrakti tietotyyppi on kokoelma tietoja sekä monia toimintoja, jotka voidaan suorittaa näille tiedoille.

Olio-ohjelmoinnin käsite

Gradi Buchan oliosuuntautuneiden ohjelmakehitysmenetelmien auktoriteetin määritelmän mukaan "olio-ohjelmointi (OOP) on ohjelmointimetodologia, joka perustuu ohjelman esittämiseen kokoelmana objekteja, joista jokainen on tietyn luokan (erityisen tyypin) toteutus, ja luokat muodostavat hierarkian periytyvyysperiaatteiden pohjalta.

Oliolähtöinen metodologia, kuten rakenteellinen metodologia, luotiin tavoitteena kurittaa suurten ohjelmistojärjestelmien kehitysprosessia ja siten vähentää niiden monimutkaisuutta ja kustannuksia.

Olio-metodologialla on samat tavoitteet kuin rakenteellisella metodologialla, mutta se käsittelee niitä eri lähtökohdista ja useimmissa tapauksissa mahdollistaa monimutkaisempien projektien hallinnan kuin rakenteellinen metodologia.

Kuten tiedätte, yksi projektin monimutkaisuuden hallinnan periaatteista on hajottaminen. Gradi Booch erottaa kaksi hajonnan tyyppiä: algoritmisen (kuten hän kutsuu rakenteellisten menetelmien tukemaa hajottamista) ja oliosuuntautuneen, joiden välinen ero hänen mielestään on seuraava: ”Algoritmeilla jakaminen keskittyy tapahtumien järjestykseen. , ja kohteiden jako antaa erityisen merkityksen tekijöille, jotka joko aiheuttavat toimia tai ovat näiden toimien sovelluskohteita."

Toisin sanoen algoritmihajotus ottaa enemmän huomioon monimutkaisen ongelman osien välisten suhteiden rakenteen, kun taas oliohajotus kiinnittää enemmän huomiota suhteiden luonteeseen.

Käytännössä on suositeltavaa käyttää molempia hajotustyyppejä: suuria projekteja luotaessa on suositeltavaa ensin käyttää oliolähtöistä lähestymistapaa, jotta luodaan yleinen objektihierarkia, joka heijastaa ohjelmoitavan tehtävän olemusta, ja sitten käyttää algoritmista hajotusta. moduuleiksi ohjelmistopaketin kehittämisen ja ylläpidon yksinkertaistamiseksi.

OO-ohjelmointi on epäilemättä yksi ammattimaisen ohjelmistokehityksen kiinnostavimmista alueista.

Objektit ja luokat

Olio-ohjelman peruslohkot ovat oliot ja luokat. Sisällöllisesti kohde voidaan esittää tunteena tai kuviteltuna ja jolla on hyvin määritelty käyttäytyminen. Siten esine voidaan joko nähdä, koskettaa tai ainakin tietää olevan siellä, esimerkiksi esittää tietokoneen muistiin tallennettuna tietona. Määritelkäämme esine noudattaen Gradi Buchan näkemystä: "Esiö on konkreettinen kokonaisuus, joka ilmentää selvästi käyttäytymistään."

Esine - se on osa ympärillämme olevaa todellisuutta, eli se on olemassa ajassa ja tilassa (ohjelmoinnin kohteen käsite otettiin ensimmäisen kerran käyttöön Simula-kielellä). Muodollisesti kohde on melko vaikea määritellä. Tämä voidaan tehdä joidenkin ominaisuuksien kautta, nimittäin: objektilla on tila, käyttäytyminen ja se voidaan yksilöidä (toisin sanoen sillä on ainutlaatuinen nimi).

Luokka - se on joukko objekteja, joilla on yhteinen rakenne ja yhteinen käyttäytyminen. Luokka on kuvaus (abstraktio), joka näyttää, kuinka tälle luokalle muodostetaan ajassa ja avaruudessa olemassa oleva muuttuja, ns. esine. Lauseilla "luokkamuuttujien kuvaus" ja "luokkaobjektien kuvaus" on sama merkitys.

Esine hänellä on kunto, käyttäytyminen ja passi (keino sen yksiselitteiseen tunnistamiseen); objektien rakenne ja käyttäytyminen kuvataan luokissa, joiden muuttujia ne ovat.

Määrittelemme nyt käsitteet tila, käyttäytyminen ja tunnistaminen esine.

Objektin tila yhdistää kaikki tietokenttänsä (staattinen komponentti, eli muuttumaton) ja kunkin kentän nykyiset arvot (dynaaminen komponentti, eli yleensä muuttuva).

Käyttäytyminen ilmaisee kohteen tilojen muutosten dynamiikkaa ja sen reaktiota saapuviin viesteihin, ts. kuinka objekti muuttaa tilojaan ja on vuorovaikutuksessa muiden objektien kanssa.

Henkilöllisyystodistus Objektin (tunnistus) on ominaisuus, jonka avulla voit erottaa kohteen muista saman tai muiden luokkien objekteista. Tunnistaminen tapahtuu yksilöllisen nimen (passin) avulla, joka on määritetty ohjelman objektille, kuten mikä tahansa muu muuttuja.

Edellä mainittiin jo, että proseduaalinen (sekä modulaarinen) lähestymistapa mahdollistaa ohjelmien rakentamisen, jotka koostuvat joukosta menettelyjä (alirutiineja), jotka toteuttavat tiettyjä algoritmeja. Toisaalta oliokeskeinen lähestymistapa edustaa ohjelmia joukkona kohteita, jotka ovat vuorovaikutuksessa keskenään. Objektit ovat vuorovaikutuksessa viestien kautta. Oletetaan, että esineemme on ympyrä. Sitten tälle objektille lähetetty viesti voisi olla: "piirrä itsesi". Kun sanomme, että viesti on lähetetty objektille, kutsumme itse asiassa jollekin toiminto tämä objekti (funktiokomponentti). Joten yllä olevassa esimerkissä kutsumme funktiota, joka piirtää ympyrän näyttöruudulle.

OOP:n perusperiaatteet

Olio-ohjelmointityylin perusperiaatteita ovat:

  • pakkaus tai kapselointi;
  • perintö;
  • polymorfismi;
  • viestin välitys.

Pakkaus (kapselointi)

sisältää tietojen ja toimintojen yhdistämisen, jotka käsittelevät näitä tietoja yhdessä objektissa. Pääsy joihinkin pakkauksen sisältämiin tietoihin voidaan joko evätä tai rajoittaa.

Esinettä luonnehditaan sarjana sen kaikista ominaisuuksista (esimerkiksi eläimille - pää, korvat, silmät jne.) ja niiden nykyiset arvot (pää - iso, korvat - pitkät, silmät - keltaiset, jne.), joten ja tälle esineelle hyväksyttävät toiminnot (kyky syödä, istua, seistä, juosta jne.). Määritetty assosiaatio yhdessä objektissa "materiaalina" komponentit(pää, korvat, häntä, tassut) ja näitä osia käsitteleviä toimia ("juoksu" -toiminto liikuttaa tassuja nopeasti) kutsutaan kapseloinniksi.

OOP:ssa dataa kutsutaan objektikentiksi ja algoritmeja kutsutaan objektimenetelmiksi.

Kapseloinnin avulla voit eristää kohteen ulkoisesta ympäristöstään mahdollisimman paljon. Se lisää merkittävästi kehitettyjen ohjelmien luotettavuutta, koska Objektiin lokalisoidut algoritmit vaihtavat suhteellisen pieniä määriä tietoa ohjelman kanssa, ja tämän tiedon määrää ja tyyppiä valvotaan yleensä huolellisesti. Tästä johtuen objektiin kapseloitujen algoritmien ja tietojen korvaaminen tai muokkaaminen ei pääsääntöisesti aiheuta huonosti jäljitettäviä seurauksia koko ohjelmalle. Toinen tärkeä kapseloinnin seuraus on kohteiden vaihtamisen helppous, siirtäminen ohjelmasta toiseen.

Perintö

Sekä rakenteellisten että oliopohjaisten metodologioiden tavoitteena on rakentaa hierarkkinen puu suhteista objektien (alitehtävien) välille. Mutta jos rakenteellinen hierarkia on rakennettu sen mukaan yksinkertainen periaate jakaa kokonaisuuden osiin,

sitten luotaessa oliosuuntautunutta hierarkiaa otetaan käyttöön erilainen näkymä samasta alkuperäisestä objektista. Oliosuuntautunut hierarkia heijastaa välttämättä pääobjektityyppien (päällekkäisten) objektityyppien ominaisuuksien periytymistä alatason (perustaisille) objektityypeille.

Gradi Boochin mukaan "perintö on objektien välinen suhde, jossa yksi objekti toistaa toisen rakenteen ja käyttäytymisen."

Perinnön periaate toimii elämässä kaikkialla ja joka päivä. Nisäkkäät ja linnut perivät elävien organismien ominaisuudet; toisin kuin kasvit, kotka ja korppi perivät lintujen yhteisen ominaisuuden - kyvyn lentää. Toisaalta leijonat, tiikerit, leopardit perivät Felidae-lahkon edustajille ominaisen "rakenteen" ja käyttäytymisen.

Oliohierarkian ylimmillä tasoilla olevilla tyypeillä ei yleensä ole konkreettisia esineitä. Ei esimerkiksi ole olemassa tiettyä elävää organismia, jota itse kutsuttaisiin "nisäkkääksi" tai "linnuksi". Tällaisia ​​​​tyyppejä kutsutaan abstrakteiksi. Tietyillä esineiden esiintymillä on yleensä OO-hierarkian alimman tason tyypit: "Gena krokotiili" on erityinen esiintymä "krokotiili" -tyyppisestä objektista, "Matroskin kissa" on erityinen esiintymä "kissa"-tyyppinen esine.

Perinnön avulla voit käyttää luokkakirjastoja ja kehittää niitä (parantaa ja muokata kirjastoluokkia) sisään erityinen ohjelma. Perinnön avulla voit luoda uusia objekteja muuttamalla tai lisäämällä ominaisuuksia olemassa oleviin. Perijäobjekti vastaanottaa kaikki esi-isän kentät ja menetelmät, mutta voi lisätä omia kenttiään, lisätä omia menetelmiään tai ohittaa samannimiset periytyneet menetelmät omilla menetelmillään.

Periytysperiaate ratkaisee objektin ominaisuuksien muuttamisen ongelman ja antaa OOP:lle kokonaisuudessaan poikkeuksellista joustavuutta. Objektien kanssa työskennellessään ohjelmoija valitsee yleensä objektin, joka on ominaisuuksiltaan lähimpänä tietyn ongelman ratkaisua, ja luo siitä yhden tai useamman jälkeläisen, joka "saa" tehdä sen, mitä ei ole toteutettu yläpäässä.

"Peri ja muuta" -periaatteen johdonmukainen täytäntöönpano sopii hyvin suurten ohjelmistoprojektien kehittämiseen ja kannustaa sitä suuresti.

Kun rakennat uuden luokan perimällä olemassa olevasta luokasta, voit:

  • lisätä uusia tietokomponentteja uuteen luokkaan;
  • lisää uusia funktiokomponentteja uuteen luokkaan;
  • korvaa uudessa luokassa vanhasta luokasta perityt funktiokomponentit.

Polymorfismi

voit käyttää samoja toimintoja ratkaisemiseen erilaisia ​​tehtäviä. Polymorfismi ilmaistaan ​​siinä, että yhden nimen alle piilotetaan erilaisia ​​​​toimintoja, joiden sisältö riippuu objektin tyypistä.

Polymorfismi on toisiinsa liittyvien objektien (eli objektien, joilla on yksi yhteinen vanhempi) ominaisuus ratkaista samankaltaisia ​​​​merkityksiä eri tavoin. Esimerkiksi "juoksu" on yhteinen useimmille eläimille. Kuitenkin jokainen heistä (leijona, norsu, krokotiili, kilpikonna) suorittaa tämän toiminnon eri tavalla.

Perinteisellä (ei-oliosuuntautuneella) ohjelmointitavalla ohjelmoija siirtää eläimiä kutsumalla erillisen aliohjelman tietylle eläimelle ja tietylle toiminnolle.

OOP:n puitteissa kohteen käyttäytymisominaisuudet määräytyvät siihen sisältyvien menetelmien avulla, ohjelmoija ilmoittaa vain, minkä objektin on suoritettava mikä sen luontaisista toiminnoista, ja (tarkasteltavassa esimerkissä) kerran kuvatut eläinobjektit. liikkuvat itseään heille ominaisella tavalla käyttäen sen sommittelumenetelmiä. Muuttamalla tietyn menetelmän algoritmia objektin jälkeläisissä ohjelmoija voi antaa näille jälkeläisille erityisiä ominaisuuksia, joita vanhemmalla ei ole. Jos haluat muuttaa menetelmää, sinun on ohitettava se lapsessa, ts. ilmoittaa samanniminen menetelmä jälkeläisessä ja toteuttaa siinä tarvittavat toimenpiteet. Tämän seurauksena kaksi samannimistä menetelmää toimii emo-objektissa ja aliobjektissa, joilla on eri algoritmipohja ja siksi ne antavat objekteille erilaisia ​​ominaisuuksia. Tätä kutsutaan objektipolymorfismiksi.

Siten esimerkissämme eläinobjektien kanssa "juoksu" -toimintoa kutsutaan polymorfiseksi toiminnaksi, ja tämän toiminnan ilmenemismuotoja kutsutaan polymorfismiksi.

Objektityypin kuvaus

Luokka tai objekti on tietorakenne, joka sisältää kenttiä ja menetelmiä. Kuten mikä tahansa tietorakenne, se alkaa varatulla sanalla ja päättyy operaattoriin loppu. Muodollinen syntaksi ei ole monimutkainen: objektityypin kuvaus saadaan korvaamalla tietuekuvauksessa oleva sana ennätys sanalla esine tai luokkaa ja lisää toimintojen ja menettelyjen ilmoitus kenttien yläpuolelle.

Tyyppi<имя типа объекта>= objekti
<поле>;
<поле>;
….
<метод>;
<метод>;
loppu;

ObjectPascalissa on erityinen varattu sana luokkaa objektien kuvaamiseen, lainattu C++:sta.

Tyyppi<имя типа объекта>= luokka
<поле>;
….
<метод>;
<метод>;
loppu;

ObjectPascal tukee molempia objektien kuvausmalleja.

Objektikomponentti on joko kenttä tai menetelmä. Kenttä sisältää nimen ja tietotyypin. Metodi on toiminto tai toiminto, joka on ilmoitettu objektityypin määrittelyssä, mukaan lukien erityiset menettelyt, jotka luovat ja tuhoavat objekteja (konstruktorit ja tuhoajat). Objektityypin määrittelyssä oleva menetelmämääritys koostuu vain otsikosta. Tämä on eräänlainen alustava kuvaus aliohjelmasta. Metodin runko noudattaa objektityypin määritystä.

Esimerkki. Otetaan käyttöön objektityyppi "ancestor", jolla on Nimi-tietokenttä ja joka voi suorittaa kaksi toimintoa:

  • julistaa: "Minä olen esi-isä!";
  • anna nimesi.

Kirjoita tPredoc = objektin nimi: merkkijono ; (objektin tietokenttä)
Menettelyilmoitus ; (objektimenetelmien ilmoitus)
Menettely OmaNimi ;
loppu;

Oliomenetelmiä toteuttavien aliohjelmien tekstit tulee antaa proseduureja ja funktioita kuvaavassa osiossa. Metodin toteutusta kuvattaessa otsikot toistavat tyyppikuvauksessa annettuja otsikoita, mutta niitä täydennetään objektin nimellä, joka erotetaan toimenpiteen nimestä pisteellä. Esimerkissämme:

Menettely tPredoc.Declaration ; (objektimenetelmän toteutus)
alkaa
writeln("Olen esi-isä!");
loppu;
Toimenpide tPredoc.MyName ; (objektimenetelmän toteutus)
alkaa
writeln("Minä olen", Nimi);
loppu;

Sisällä menetelmäkuvaukset kentille ja menetelmille tämän tyyppistä viitataan yksinkertaisesti nimellä. Joten MyName-metodi käyttää Nimi-kenttää ilmoittamatta eksplisiittisesti sen omistajuudesta objektiin, ikään kuin implisiittinen lauseke suoritettaisiin<переменная_типа_объект>tehdä.

Objektit tarkoittavat myös objektityypin muuttujia - niitä kutsutaan kopioita. Kuten kaikilla muuttujilla, ilmentymällä on nimi ja tyyppi: ne on ilmoitettava.

…….(objektityypin ilmoitus ja kuvaus sen menetelmistä)
var v 1: tPredoc ; (objektin esiintymän ilmoitus)
alkaa
v1. Nimi:= "Petrov Nikolai Ivanovich";
v1.Declaration;
v1.MyName
loppu.

V1-objektin tietokentän käyttäminen on sama syntaksi kuin tietuekenttien käyttäminen. Objektin ilmentymän menetelmien kutsuminen tarkoittaa, että määritettyä menetelmää kutsutaan objektin v 1 tiedoilla. Tämän seurauksena rivit näkyvät näytöllä

Olen esi-isä!
Olen Nikolai Ivanovitš Petrov

Tietueiden tapaan objektityyppien muuttujien kenttiä voidaan käyttää joko määritetyillä tunnisteilla tai with-käskyllä.

Esimerkiksi ohjelman tekstissä operaattoreiden sijaan

on mahdollista käyttää tämän tyyppistä with-operaattoria

kanssa v1 do
alkaa
Nimi:= "Petrov Nikolai Ivanovich";
julistus ;
Nimeni
loppu;

Lisäksi with-käskyn käyttö objektityyppien sekä tietueiden kanssa ei ole vain mahdollista, vaan myös suositeltavaa.

Tyyppihierarkia (perintö)

Tyypit voidaan järjestää hierarkiaan. Objekti voi periä komponentteja toisesta objektityypistä. Perijäobjekti on lapsi. Esine, joka peritään, on esi-isä. Korostamme, että periytyminen koskee vain tyyppejä, ei objektien esiintymiä.

Jos objektityyppi (esi-, emo) otetaan käyttöön ja sitä on täydennettävä kentillä tai menetelmillä, otetaan käyttöön uusi tyyppi, joka julistetaan ensimmäisen seuraajaksi (jälkeläinen, alatyyppi) ja vain uudet kentät ja menetelmät kuvataan. Jälkeläinen sisältää kaikki esi-isätyypin kentät. Huomaa, että esi-isän kentät ja menetelmät ovat lapsen käytettävissä ilman erityisiä ohjeita. Jos jälkeläinen kuvaus toistaa esivanhemman kenttien tai menetelmien nimet, uudet kuvaukset ohittavat esivanhemman kentät ja menetelmät.

OOP alkaa aina perusluokalla. Tämä on perusobjektin malli. Seuraava askel on määritellä uusi luokka, jota kutsutaan johdetuksi luokaksi ja joka on perusluokan laajennus.

Johdettu luokka voi sisältää lisämenetelmiä, joita ei ole perusluokassa. Se voi määrittää menetelmät uudelleen (tai jopa poistaa ne kokonaan).

Johdettu luokka ei saa ohittaa kaikkia perusluokan menetelmiä. Jokainen uusi objekti perii perusluokan ominaisuudet; sinun tarvitsee vain määrittää ne menetelmät, jotka ovat uusia tai joita on muutettu. Kaikki muut perusluokan menetelmät katsotaan osaksi johdettua luokkaa. Tämä on kätevä, koska... Kun menetelmää muutetaan perusluokassa, se muuttuu automaattisesti kaikissa johdetuissa luokissa.

Perintöprosessi voi jatkua. Luokasta, joka on johdettu perusluokasta, voi itse tulla perusluokka muille johdetuille luokille. Tällä tavalla OO-ohjelmat luovat luokkahierarkian.

Useimmiten luokkahierarkian rakennetta kuvataan puuna. Puun latvat vastaavat luokkia ja juuri luokkaa, joka kuvaa jotain yhteistä (yleisintä) kaikille muille luokille.

Tietokenttien ja niiden emotyyppien menetelmien periminen alityyppien mukaan suoritetaan seuraavien sääntöjen mukaisesti.

Sääntö 1. Päätyypin tietokentät ja menetelmät perivät kaikki sen alityypit riippumatta hierarkian välitasojen lukumäärästä.

Sääntö 2. Pääsy vanhempien tyyppien kenttiin ja menetelmiin minkä tahansa alityyppien määritelmän sisällä suoritetaan ikään kuin ne olisi kuvattu itse lapsityypeissä.

Sääntö 3. Mikään alityyppi ei voi käyttää ylätyyppiensä kenttätunnisteita.

Sääntö 4. Lapsityyppi voi määrittää mielivaltaisen määrän omia menetelmiään ja tietokenttiään.

Sääntö 5. Kaikki ylätason menetelmän tekstin muutokset vaikuttavat automaattisesti kaikkiin sitä kutsuvien alityyppien menetelmiin.

Sääntö 6. Toisin kuin tietokentissä, alityyppien menetelmätunnisteet voivat olla samat kuin ylätyyppien menetelmän nimet. Tässä tapauksessa lapsimenetelmän sanotaan ohittavan (sulkevan) samannimisen ylätason menetelmän. Lapsityypin sisällä, kun määritetään tällaisen menetelmän nimeä, kutsutaan alimenetelmää, ei vanhempia.

Jatketaan esimerkillämme. Esittelemämme tPredoc-kantatyypin lisäksi voimme esitellä jälkeläistyyppejä:

ture tSon= object(tPredoc) (Tyyppi, joka perii tPredocin)
menettelyn julistus; (päällekkäiset esivanhemmat)
menettely My Name (Predoc: tPredoc);
loppu;

Tyyppi tGrandSon=object(tSon) (tyyppi periytyy tSonista)
menettely Eurovoc-avainsana julistus ; (päällekkäiset esivanhemmat)
loppu;

Esivanhempaintyypin nimi annetaan suluissa sanan jälkeen esine. Olemme luoneet kolmen tyypin perinnöllisen hierarkian: tSon ("poika") on tPredoc-tyypin perillinen ja tGrandSon ("pojanpoika") -tyyppi on tSon-tyypin perillinen. tSon-tyyppi ohittaa Declaration- ja My N a m e -menetelmät, mutta perii Nimi-kentän. tGrandSon-tyyppi ohittaa vain Declaration-menetelmän ja perii Nimi-kentän yhteiseltä esi-isältään ja ohitetun Declaration-menetelmän välittömältä esi-isältään (tyyppi tSon).

Selvitetään, mitä tarkalleen haluamme muuttaa päämenetelmissä. Tosiasia on, että "pojan" täytyy julistaa hieman eri tavalla kuin esi-isänsä, nimittäin sanoa: "Minä olen isä!"

menettelyä tSon.Declaration ; (jälkeläisten objektien menetelmien toteutus)
alkaa
writeln("Minä olen isä!");
loppu;

Ja nimeään antaessaan "pojan" on annettava seuraavat tiedot:

  • minä<фамилия имя отчество >
  • Minä olen poika<фамилия имя отчество своего предка>

menettelyä tSon .My Name (predoc: tPredoc);
alkaa
peritty Mu nimi; (soita välittömän esivanhemman menetelmäksi)
writeln("Minä olen poika", predoc.Nimi, "a");
loppu;

Esimerkissämme My Name -metodin jälkeläinen tSon kutsuu samannimistä metodia sen välittömässä esi-isätyypissä tPredoc. Tämä kutsu sisältyy direktiiviin peritty, jonka jälkeen kutsutaan välittömän esivanhemman menetelmää. Jos jollakin hierarkian tasolla on tarve kutsua kaukaisen esivanhemman menetelmää jossain lapsityypissä, se voidaan tehdä käyttämällä hyväksyttyä tunnistetta, ts. ilmaisee selkeästi pääobjektin tyypin nimen ja pisteellä erotettuna sen menetelmän nimen:

Nyt käsitellään "pojanpoika". Menetelmä, jolla "pojanpoika" sanoo nimensä, on täsmälleen sama kuin sen välitön esi-isä (tyyppi tSon), joten tätä menetelmää ei tarvitse ohittaa, on parempi periä tämä menetelmä automaattisesti ja käyttää sitä omana. Mutta Declaration-menetelmässä sinun on julistettava "Olen pojanpoika!", joten menetelmä on määritettävä uudelleen.

menettelyä tGrandSon.Declaration;
alkaa
writeln("Olen pojanpoika!");
loppu;

Tarkastellaan esimerkkiä ohjelmasta, jossa määritämme tPredoc-tyypin esiintymän, kutsumme sitä "isoisäksi", tSon-tyypin esiintymää "isä" ja tGrandSon-tyypin esiintymää "pojanpoika". Pyydetään heitä esittelemään itsensä.

Esimerkkiohjelma OOP:lla

(ohjelman nimi)
……………….
(osio tyyppien kuvauksista, mukaan lukien objektityypit tPredoc, tSon, tGrandSon)
(Huomaa! Objektityyppien ilmentymiä voidaan kuvata tyyppisinä vakioina, minkä olemme tehneet alla esimerkissä)
konst ded: tPredoc = (Nimi: "Nikolai Ivanovich Petrov");
otec: tSon = (Nimi: "Petrov Sergey Nikolaevich");
vnuk: tGrandSon = (Nimi: "Petrov Oleg Sergeevich");
(osa proseduurien ja toimintojen kuvauksista, johon kaikki objektityypeissä määritellyt menetelmät on kirjoitettava)
alkaa
julistus; (kutsutaan yhteisiksi esivanhemmiksi)
ded.My Name;
kirjoitettu;
otec.Declaration;
otec.MyName(ded); (tSon-tyypin otec-objektin kutsumismenetelmät)
kirjoitettu;
vnuk.Declaration; (tGrandSon-tyypin vnuk-objektin kutsumismenetelmät)
vnuk.OmaNimi(otec);
loppu.

Ohjelmamme näyttää:

Esimerkki tuloksen näyttämisestä

Olen esi-isä!
Olen Nikolai Ivanovitš Petrov

Olen isä!
Olen Petrov Sergei Nikolajevitš
Olen Petrov Nikolai Ivanovichin poika

Olen pojanpoika!
Olen Petrov Oleg Sergeevich
Olen Sergei Nikolajevitš Petrovin poika

Huomaa, että menettelyn otsikossa tSon. MyNamelle annetaan parametrina tPredoc-tietotyyppi, ja tätä menettelyä käytettäessä sille välitetään sekä tPredoc- että tSon-tyyppiset muuttujat. Tämä on mahdollista, koska esi-isä on tyyppiyhteensopiva jälkeläistensä kanssa. Päinvastoin ei pidä paikkaansa. Jos korvaamme tSon toimenpiteen otsikossa. MyName kuvattaessa tPredoc-tyypin parametreja tSonissa, kääntäjä ilmoittaa tyypin yhteensopimattomuuden, kun käytetään ded-muuttujaa otec-rivillä. OmaNimi (poistettu).

Polymorfismi ja virtuaaliset menetelmät

Polymorfismi– Tämä on toisiinsa liittyvien objektien (eli objektien, joilla on sama vanhempi) ominaisuus ratkaista samankaltaisia ​​ongelmia eri tavoilla.

Kahta tai useampaa luokkaa, jotka on johdettu samasta perusluokasta, kutsutaan polymorfisiksi. Tämä tarkoittaa, että niillä voi olla yhteisiä ominaisuuksia, mutta myös omat ominaisuutensa.

OOP:n sisällä objektin käyttäytymisominaisuudet määräytyvät sen sisältämien menetelmien mukaan. Muuttamalla tietyn menetelmän algoritmia objektin jälkeläisissä ohjelmoija voi antaa näille jälkeläisille erityisiä ominaisuuksia, joita vanhemmalla ei ole. Jos haluat muuttaa menetelmää, sinun on ohitettava se lapsessa, ts. ilmoittaa samanniminen menetelmä jälkeläisessä ja toteuttaa siinä tarvittavat toimenpiteet. Tämän seurauksena kaksi samannimistä menetelmää toimii emo-objektissa ja aliobjektissa, joilla on eri algoritmipohja ja siksi ne antavat objekteille erilaisia ​​ominaisuuksia. Tätä kutsutaan objektipolymorfismiksi.

Yllä käsitellyssä esimerkissä kaikilla kolmella objektityypillä tPredoc, tSon ja tGrandSon on samat menetelmät Declaration ja MyName. Mutta tSon-objektityyppi toteuttaa MyName-menetelmän hieman eri tavalla kuin sen esi-isä. Ja kaikki kolme samannimistä ilmoitusmenetelmää suoritetaan eri tavalla jokaiselle objektille.

Objektimenetelmät ovat staattisia, virtuaalisia ja dynaamisia.

Staattiset menetelmät

sisällytetty ohjelmakoodiin kääntämisen aikana. Tämä tarkoittaa, että ennen ohjelman käyttöä määritetään, mikä proseduuri tietyssä pisteessä kutsutaan. Kääntäjä määrittää, minkä tyyppistä objektia tietyssä kutsussa käytetään, ja korvaa kyseisen objektin menetelmällä.

Objektit eri tyyppejä voi olla samanniisiä staattisia menetelmiä. Tässä tapauksessa vaadittu menetelmä määräytyy objektiinstanssin tyypin mukaan.

Tämä on kätevää, koska erityyppisten objektien menetelmät, joilla on sama merkitys, voidaan nimetä samalla tavalla, mikä yksinkertaistaa sekä tehtävien että ohjelmien ymmärtämistä. Staattinen päällekkäisyys on polymorfismin ensimmäinen askel. Samat nimet ovat ohjelmoinnin mukavuuskysymys, eivät periaate.

Virtuaaliset menetelmät

toisin kuin staattiset, ne on kytketty pääkoodiin ohjelman suoritusvaiheessa. Virtuaaliset menetelmät tarjoavat mahdollisuuden määrittää objektin tyyppi ja ilmentyä suorituksen aikana ja kutsua sitten menetelmiä kyseiselle objektille.

Tämä pohjimmiltaan uusi mekanismi, jota kutsutaan myöhäiseksi sitomiseksi, tarjoaa polymorfismin, ts. toinen tapa käyttäytyminen erilaisille mutta homogeenisille (perinnön merkityksessä) kohteille.

Virtuaalimetodin kuvaus eroaa tavallisen menetelmän kuvauksesta lisäämällä funktiosanan menetelmän otsikon perään virtuaalinen .

menettelytapa Menetelmä (parametriluettelo); virtuaalinen;

Virtuaalisten menetelmien käytöllä objektityyppihierarkiassa on tiettyjä rajoituksia:

  • jos menetelmä on ilmoitettu virtuaaliseksi, niin jälkeläistyypissä sitä ei voi ohittaa staattisella menetelmällä;
  • objektit, joilla on virtuaalisia menetelmiä, alustetaan erityisillä proseduureilla, jotka periaatteessa ovat myös virtuaalisia ja joita kutsutaan rakentaja ;
  • päällekkäisten virtuaalisten proseduurien ja funktioiden otsikoissa olevien muuttujien ja funktiotyyppien luetteloiden on vastattava täysin toisiaan;

Yleensä päällä rakentaja kohde-ilmentymän alustustyö määrätään: aloitusarvojen määrittäminen kenttiin, ensimmäinen näyttö näytöllä jne.

Ohjelmoijan siihen sisällyttämien toimien lisäksi suunnittelija valmistelee mekanismin myöhäinen sidonta virtuaalisia menetelmiä. Tämä tarkoittaa, että ennen kuin mitään virtuaalista menetelmää kutsutaan, jokin konstruktori on suoritettava.

Konstruktori on erityinen menetelmä, joka alustaa virtuaalisia menetelmiä sisältävän objektin. Rakentajan otsikko näyttää tältä:

konstruktori Method(parametriluettelo);

Varattu sana rakentaja korvaa sanat menettely ja virtuaalinen .

Konstruktorin pää- ja erityistarkoitus on muodostaa yhteyksiä virtuaaliseen menetelmätaulukkoon (VMT) - rakenteeseen, joka sisältää viittauksia virtuaalisiin menetelmiin. Konstruktori siis alustaa objektin muodostamalla yhteyden objektin ja VMT:n välille virtuaalisten menetelmäkoodien osoitteilla. Myöhäinen sitominen tapahtuu alustuksen aikana.

Jokaisella objektilla on oma VMT-virtuaalinen menetelmätaulukko. Tämä sallii samannimisen menetelmän kutsua erilaisia ​​proseduureja.

Mainittuamme rakentajan, meidän pitäisi myös sanoa tuhoaja. Sen rooli on päinvastainen: suorita toimintoja, jotka viimeistelevät työskentelyn objektin kanssa, sulje kaikki tiedostot, tyhjennä dynaaminen muisti, tyhjennä näyttö jne.

Destruktorin otsikko näyttää tältä:

tuhoaja Valmis ;

Tuhoajien päätarkoitus on tuhota VMT tästä esineestä. Usein tuhoaja ei tee mitään ja on tyhjä menettely.

tuhoaja Valmis ;
alkaa loppu ;

pohjimmiltaan käytti ohjelmointiparadigmaa - tavoitteena oli luoda koodia, joka toimii asianmukaisesti dataan. Tämä lähestymistapa on hyvä pienten ongelmien ratkaisemiseen, mutta se aiheuttaa monia vaikeita ongelmia, kun yrittää luoda suuri ohjelmistojärjestelmät .

Yksi vaihtoehdoista ohjelmointi On olio-ohjelmointi, mikä Todella auttaa selviytymään ohjelmien epälineaarisesti kasvavasta monimutkaisuudesta niiden määrän kasvaessa. Ei kuitenkaan pidä päätellä, että olio-ohjelmointiparadigman käyttö takaa onnistuneen ratkaisun kaikkiin ongelmiin.

Ohjelmoinnin ammattilaiseksi tullaksesi tarvitset lahjakkuutta, luovuutta, älykkyyttä, tietoa, logiikkaa, kykyä rakentaa ja käyttää abstraktioita ja mikä tärkeintä, kokemusta.

Tässä osiossa jatkamme olio-ohjelmoinnin peruskäsitteiden johdatusta, jonka aloitimme kirjan ensimmäisessä luvussa. Ensin käsitellään eri ohjelmointikielille yhteisiä OOP-konsepteja ja sitten niiden toteutusta Java-kielellä.

Sinun tulee olla tietoinen siitä, että olioohjelmoinnin kurssia opetetaan perustutkinto-opiskelijoille koko lukukauden ajan, ja siksi alla oleva materiaali edustaa vain hyvin perusjohdantoa OOP:n maailmaan. Kirjassa on paljon kattavampi käsitys monista oliosuunnitteluun, suunnitteluun ja ohjelmointiin liittyvistä kysymyksistä, ja kirjan kolmannesta luvusta löydät erittäin selkeän kuvauksen kaikista oliosuuntautuneista näkökohdista. Java kieli.

OOP:n peruskäsitteet

Olio-ohjelmointi tai OOP (olio-ohjelmointi) - ohjelmointimetodologia perustuu ohjelman esittämiseen kokoelmana objekteja, joista jokainen on tietyn tyyppinen toteutus mekanismin avulla viestien välittäminen ja luokat järjestetään perintöhierarkia.

OOP:n keskeinen elementti on abstraktio. Tiedot muunnetaan objekteiksi abstraktion avulla, ja näiden tietojen käsittelysekvenssi muuttuu näiden objektien välillä välitetyksi viestijoukoksi. Jokaisella esineellä on oma ainutlaatuinen käyttäytymisensä. Objekteja voidaan käsitellä konkreettisina kokonaisuuksina, jotka vastaavat viesteihin, jotka käskevät niitä suorittamaan jonkin toiminnon.

OOP:lle on tunnusomaista seuraavat periaatteet (Alan Kayn mukaan):

  • kaikki on esine;
  • laskelmat suoritetaan objektien välisen vuorovaikutuksen (tiedonvaihdon) kautta, jossa yksi kohde vaatii toisen objektin suorittamaan jonkin toiminnon; objektit ovat vuorovaikutuksessa lähettämällä ja vastaanottamalla viestejä; viesti on pyyntö suorittaa toiminto, jota täydennetään joukko argumentteja, joita voidaan tarvita toimintoa suoritettaessa;
  • jokaisella esineellä on itsenäinen muisti, joka koostuu muista esineistä;
  • jokainen objekti edustaa luokkaa, joka ilmaisee tietyn tyyppisten objektien yleiset ominaisuudet;
  • asetettu luokassa toiminnallisuutta(esinekäyttäytyminen); siten kaikki objektit, jotka ovat saman luokan esiintymiä, voivat suorittaa samat toiminnot;
  • luokat on järjestetty yhdeksi puurakenteeksi, jolla on yhteinen juuri, ns perintöhierarkia; tietyn luokan esiintymiin liittyvä muisti ja käyttäytyminen ovat automaattisesti kaikkien hierarkkisen puun alempana olevien luokkien käytettävissä.

Määritelmä 10.1. Abstraktio- menetelmä ongelman ratkaisemiseksi, jossa yhdistetään erilaisia ​​esineitä yleinen käsite(käsite), ja sitten ryhmiteltyjä kokonaisuuksia pidetään yhden luokan elementteinä.

Abstraktio avulla voit erottaa ohjelman fragmentin loogisen merkityksen sen toteuttamisongelmasta, jakamisesta ulkoinen kuvaus(rajapinta) esineestä ja sen sisäinen organisaatio(toteutus).

Määritelmä 10.2. Kapselointi- tekniikka, jossa objektin käyttöliittymän kannalta merkityksetöntä tietoa piilotetaan sen sisään.

Määritelmä 10.3. Perintö- objektien ominaisuus, jonka kautta luokan esiintymät pääsevät käsiksi esivanhempainluokkien tietoihin ja menetelmiin määrittelemättä niitä uudelleen.

Perinnön ansiosta eri tietotyypit voivat jakaa saman koodin, mikä johtaa pienempään koodiin ja parempaan toimivuuteen.

Määritelmä 10.4.

Java on oliokieli. Tämä tarkoittaa, että sinun on kirjoitettava Java-ohjelmia käyttäen olio-tyyliä. Ja tämä tyyli perustuu objektien ja luokkien käyttöön ohjelmassa. Yritetään esimerkkien avulla ymmärtää, mitä luokat ja objektit ovat, sekä kuinka soveltaa OOP:n perusperiaatteita käytännössä: abstraktio, periytyminen, polymorfismi ja kapselointi.

Mikä on esine?

Maailma, jossa elämme, koostuu esineistä. Jos katsomme ympärillemme, näemme, että ympärillämme on taloja, puita, autoja, huonekaluja, astioita, tietokoneita. Kaikki nämä kohteet ovat esineitä, ja jokaisella niistä on joukko erityisiä ominaisuuksia, käyttäytymistä ja tarkoitusta. Olemme tottuneet esineisiin ja käytämme niitä aina tiettyihin tarkoituksiin. Esimerkiksi jos meidän on päästävä töihin, käytämme autoa, jos haluamme syödä, käytämme astioita ja jos haluamme rentoutua, tarvitsemme mukavan sohvan. Ihminen on tottunut ajattelemaan objektiivisesti ratkaistakseen ongelmia Jokapäiväinen elämä. Tämä oli yksi syistä objektien käyttämiseen ohjelmoinnissa, ja tätä lähestymistapaa ohjelmien luomiseen kutsuttiin oliosuuntautuneeksi. Otetaan esimerkki. Kuvittele, mitä olet kehittänyt uusi malli puhelimeen ja haluat aloittaa massatuotannon. Puhelinsuunnittelijana tiedät, mihin se on tarkoitettu, miten se toimii ja mistä osista se koostuu (kotelo, mikrofoni, kaiutin, johdot, painikkeet jne.). Kuitenkin vain sinä tiedät, kuinka nämä osat liitetään. Et kuitenkaan aio valmistaa puhelimia henkilökohtaisesti, vaan sinulla on tätä varten koko henkilökunta työntekijää. Jotta sinun ei tarvitse joka kerta selittää, kuinka puhelimen osat kytketään, ja jotta kaikki tuotannossa olevat puhelimet olisivat samanlaisia, sinun on tehtävä piirustus ennen niiden valmistuksen aloittamista. kuvaus puhelimen rakenteesta. OOP:ssa tällaista kuvausta, piirustusta, kaaviota tai mallipohjaa kutsutaan luokaksi, josta luodaan olio ohjelmaa suoritettaessa. Luokka on kuvaus objektista, jota ei ole vielä luotu, kuten yleinen mallipohja, joka koostuu kentistä, menetelmistä ja konstruktorista, ja objekti on tämän kuvauksen perusteella luodun luokan esiintymä.

Abstraktio

Mietitään nyt, kuinka voimme siirtyä todellisen maailman esineestä ohjelman esineeseen käyttämällä esimerkkiä puhelinta. Tämän viestintävälineen historia on yli 100 vuotta ja moderni puhelin, toisin kuin edeltäjänsä 1800-luvulta, on paljon monimutkaisempi laite. Kun käytämme puhelinta, emme ajattele sen rakennetta ja sen sisällä tapahtuvia prosesseja. Käytämme vain puhelimen kehittäjien toimittamia toimintoja - painikkeita tai kosketusnäyttö valitaksesi numeron ja soittaaksesi puheluita. Yksi ensimmäisistä puhelinliittymistä oli nuppi, jota käänsit soittaaksesi puhelun. Tämä ei tietenkään ollut kovin kätevää. Kädensija hoiti kuitenkin tehtävänsä kunnolla. Kun katsot nykyaikaisinta ja aivan ensimmäistä puhelinta, voit heti tunnistaa tärkeimmät yksityiskohdat, jotka ovat tärkeitä sekä 1800-luvun lopun laitteelle että ultramodernille älypuhelimelle. Tämä tarkoittaa puhelun soittamista (numeron valitsemista) ja puhelun vastaanottamista. Pohjimmiltaan tämä tekee puhelimesta puhelimen eikä jotain muuta. Nyt olemme soveltaneet periaatetta OOP:ssa - korostaen eniten tärkeitä ominaisuuksia ja tietoa kohteesta. Tätä periaatetta kutsutaan abstraktioksi. OOP:n abstraktio voidaan määritellä myös tapaksi esittää todellisen ongelman elementtejä ohjelman kohteina. Abstraktio liittyy aina jonkin esineiden tai esineiden ominaisuuksia koskevien tietojen yleistämiseen, joten pääasia on erottaa ratkaisevan ongelman yhteydessä merkittävä tieto merkityksettömästä tiedosta. Tässä tapauksessa abstraktiotasoja voi olla useita. Yritetään soveltaa abstraktioperiaatetta puhelimiimme. Korostetaan ensin yleisimmät puhelintyypit ensimmäisestä nykypäivään. Ne voidaan esittää esimerkiksi kuvassa 1 esitetyn kaavion muodossa. Nyt abstraktiota käyttämällä voimme korostaa yleistä tietoa tästä objektihierarkiasta: yleinen abstrakti objektityyppi on puhelin, Yleiset luonteenpiirteet puhelin - sen luomisvuosi ja yhteinen käyttöliittymä - kaikki puhelimet pystyvät vastaanottamaan ja lähettämään puheluita. Tältä se näyttää Javassa: julkinen abstrakti luokka AbstractPhone ( yksityinen int vuosi; julkinen AbstractPhone (int vuosi) ( tämä . vuosi = vuosi; ) julkinen abstrakti void call (int outputNumber) ; julkinen abstrakti void ring (int inputNumber) ; ) On Tämän abstraktin luokan perusteella voimme luoda ohjelmaan uudentyyppisiä puhelimia käyttämällä muita Java OOP -perusperiaatteita, joita tarkastelemme alla.

Kapselointi

Käyttämällä abstraktioita korostamme yleistä kaikille esineille. Jokainen puhelinmalli on kuitenkin yksilöllinen ja hieman erilainen kuin muut. Kuinka voimme vetää rajat ohjelmaan ja osoittaa tämän yksilöllisyyden? Kuinka voimme varmistaa, että kukaan käyttäjistä ei voi vahingossa tai tahallaan rikkoa puhelintamme tai yrittää muuntaa mallia toiseksi? Todellisten esineiden maailmaan vastaus on ilmeinen: sinun on laitettava kaikki osat puhelimen runkoon. Loppujen lopuksi, jos emme tee tätä ja jätämme kaikki puhelimen sisäosat ja niitä yhdistävät johdot ulkopuolelle, löytyy varmasti utelias kokeilija, joka haluaa "parantaa" puhelimemme toimintaa. Välttääkseen tällaisten häiriöiden kohteen suunnittelussa ja toiminnassa OOP käyttää kapselointiperiaatetta - toista OOP:n perusperiaatetta, jossa objektin attribuutit ja käyttäytyminen yhdistetään yhteen luokkaan, objektin sisäinen toteutus on piilotettu. käyttäjälle, ja objektin kanssa työskentelyä varten tarjotaan avoin käyttöliittymä. Ohjelmoijan tehtävänä on määrittää, mitkä attribuutit ja menetelmät ovat julkisesti saatavilla ja mitkä ovat objektin sisäisiä toteutuksia, joita ei pidä muuttaa.

Kapselointi ja kulunvalvonta

Oletetaan, että tuotannon aikana puhelimen takaosaan kaiverretaan tiedot siitä: valmistusvuosi tai valmistajan yrityksen logo. Tämä tieto on varsin ominaista tämä malli- hänen tilansa. Voimme sanoa, että puhelimen kehittäjä huolehti näiden tietojen muuttumattomuudesta - on epätodennäköistä, että kukaan ajattelisi kaiverruksen poistamista. Java-maailmassa tulevaisuuden objektien tila kuvataan luokassa kenttien avulla ja niiden käyttäytyminen menetelmien avulla. Mahdollisuus muuttaa tilaa ja käyttäytymistä suoritetaan kenttien ja menetelmien käyttöoikeusmuutoksilla - yksityinen, suojattu, julkinen , ja oletuksena (oletuskäyttö). Päätimme esimerkiksi, että luomisvuosi, puhelimen valmistajan nimi ja yksi menetelmistä kuuluvat luokan sisäiseen toteutukseen, eivätkä muut ohjelman objektit voi muuttaa niitä. Koodia käyttämällä luokkaa voidaan kuvata seuraavasti: public class SomePhone ( yksityinen int vuosi; yksityinen String yritys; julkinen SomePhone (int vuosi, String yritys) ( tämä . vuosi = vuosi; tämä . yritys = yritys; ) yksityinen void openConnection ( ) ( / /findComutator //openNewConnection... ) public void call () ( openConnection () ; System. out. println ("Soittaminen numeroon") ; ) public void ring () ( System. out. println ("Ding" -ding") ; ) ) Muokkaus yksityinen tekee luokan kentät ja menetelmät käytettävissä vain kyseisessä luokassa. Tämä tarkoittaa, että voit käyttää yksityinen kentät ulkopuolelta on mahdotonta, aivan kuten ei ole mitään tapaa kutsua yksityinen menetelmiä. OpenConnection-menetelmän pääsyn piilottaminen jättää meille myös vapauden muuttaa tämän menetelmän sisäistä toteutusta, koska muut objektit eivät taatusti käytä tätä menetelmää, eikä se häiritse niiden työtä. Jotta voimme työskennellä objektimme kanssa, jätämme kutsu- ja soittomenetelmät auki modifierin avulla julkinen . Julkisten menetelmien tarjoaminen objektin kanssa työskentelyyn on myös osa kapselointimekanismia, koska jos pääsy objektiin evätään kokonaan, siitä tulee hyödytöntä.

Perintö

Katsotaanpa vielä puhelintaulukkoa. Näet, että se edustaa hierarkiaa, jossa alla olevalla mallilla on kaikki ylempänä haaran mallien ominaisuudet sekä omansa. Esimerkiksi älypuhelin käyttää matkapuhelinverkkoa viestintään (sillä on matkapuhelimen ominaisuudet), se on langaton ja kannettava (sillä on ominaisuuksia langaton puhelin) ja voi vastaanottaa ja soittaa puheluita (käyttäen puhelimen ominaisuuksia). Tässä tapauksessa voimme puhua objektin ominaisuuksien periytymisestä. Ohjelmoinnissa perinnöllä tarkoitetaan olemassa olevien luokkien käyttöä uusien määrittämiseen. Katsotaanpa esimerkkiä älypuhelinluokan luomisesta periytymisen avulla. Kaikki langattomat puhelimet toimivat paristot, joilla on tietty käyttöikä tunneissa. Lisätään siis tämä ominaisuus langattoman puhelimen luokkaan: julkinen abstrakti luokka WirelessPhone laajentaa AbstractPhone ( yksityinen int tunti; julkinen WirelessPhone (int vuosi, int tunti) ( super (vuosi) ; tämä . tunti = tunti; ) ) Matkapuhelimet perivät ominaisuudet langattoman puhelimen, Lisäsimme tähän luokkaan myös soitto- ja soittomenetelmien toteutuksen: julkinen luokka CellPhone laajentaa WirelessPhonea ( julkinen matkapuhelin (int vuosi, int tunti) ( super (vuosi, tunti); ) @Override public void call ( int outputNumber) ( System. out. println ("Soittonumero " + outputNumber) ; ) @Override public void ring (int inputNumber) ( System. out. println ( "Tilaaja soittaa sinulle"+ inputNumber) ; ) ) Ja lopuksi älypuhelinluokka, jolla, toisin kuin klassisissa matkapuhelimissa, on täysi käyttöjärjestelmä. Voit lisätä älypuhelimeesi uusia tämän käyttöjärjestelmän tukemia ohjelmia, mikä laajentaa sen toimivuutta. Koodia käyttämällä luokkaa voidaan kuvata seuraavasti: public luokka Älypuhelin laajentaa CellPhonea ( private String operationSystem; public Smartphone (int vuosi, int tunti, String operationSystem) ( super (vuosi, tunti); this . operationSystem = operationSystem; ) public void install (String-ohjelma) ( System. out. println ("I install" + program + "for" + operationSystem) ; ) ) Kuten näette, loimme hyvin vähän uutta koodia kuvaamaan älypuhelinluokkaa, mutta saimme uuden luokka uusilla toiminnoilla. Tämän OOP javan periaatteen käyttäminen voi merkittävästi vähentää koodin määrää ja siten helpottaa ohjelmoijan työtä.

Polymorfismi

Jos tarkastelemme kaikkia puhelinmalleja, niin mallien ulkonäön ja suunnittelun eroista huolimatta voimme tunnistaa niissä joitain yleisiä käyttäytymismalleja - niillä kaikilla voi vastaanottaa ja soittaa puheluita ja niillä on melko selkeä ja yksinkertainen ohjauspainikkeet. Sovellettaessa yhtä meille jo tuttua OOP:n perusperiaatetta, abstraktiota ohjelmointitermeissä, voidaan sanoa, että puhelinobjektilla on yksi yhteinen rajapinta. Puhelimen käyttäjät voivat siis varsin mukavasti käyttää eri malleja samoilla ohjauspainikkeilla (mekaaninen tai kosketus), menemättä laitteen teknisiin yksityiskohtiin. Käytät siis jatkuvasti kännykkä, ja voit soittaa helposti lankapuhelimesta. OOP:n periaate, kun ohjelma voi käyttää objekteja, joilla on sama käyttöliittymä ilman tietoa sisäinen rakenne objektia kutsutaan polymorfismi . Kuvitellaan, että ohjelmassamme meidän on kuvattava käyttäjä, joka voi käyttää mitä tahansa puhelinmallia soittaakseen toiselle käyttäjälle. Näin voit tehdä sen: julkinen luokka User ( yksityinen Merkkijonon nimi; julkinen käyttäjä (merkkijonon nimi) ( tämä . nimi = nimi; ) public void callAnotherUser (int number, AbstractPhone phone) ( // tämä on polymorfiaa - abstraktin tyypin AbstractPhone puhelin käyttäminen koodissa! puhelin. soita numeroon) ; ) ) ) Nyt kuvataan eri puhelinmalleja. Yksi ensimmäisistä puhelinmalleista: julkinen luokka ThomasEdisonPhone laajentaa AbstractPhonea ( julkinen ThomasEdisonPhone (int vuosi) ( super (vuosi) ; ) @Override public void call (int outputNumber) ( System. out. println ("Kierrä nuppia") ; System ulos .println( "Anna puhelinnumerosi, sir") ; ) @Override public void ring (int inputNumber) ( System. out. println ( "Puhelin soi" ) ; ) ) Normaali lankapuhelin: julkinen luokka Puhelin laajenee AbstractPhone ( julkinen Puhelin (int vuosi) ( super (vuosi) ; ) @Override public void call (int outputNumber) ( System. out. println ("Soittonumero" + outputNumber) ; ) @Override public void ring (int inputNumber) ( System. out. println ( "Puhelin soi" ) ; ) ) Ja lopuksi siisti videopuhelin: julkisen luokan VideoPhone laajentaa AbstractPhonea ( julkinen VideoPhone (int vuosi) ( super (vuosi) ; ) @Override julkinen void call (int outputNumber) ( System. out. println ( "Yhdistän tilaajalle videokanavan"+ outputNumber); ) @Override public void ring (int inputNumber) ( System. out. println ( "Sinulla on saapuva videopuhelu..."+ inputNumber) ; ) ) Luodaan oliot main()-metodissa ja testataan callAnotherUser-metodia: AbstractPhone firstPhone = new ThomasEdisonPhone (1879) ; AbstractPhone puhelin = uusi puhelin (1984); AbstractPhone videoPhone= uusi VideoPhone (2018) ; User user = uusi käyttäjä ("Andrey" ) ; käyttäjä. soitaToiselleKäyttäjälle(224466, ensimmäinenPuhelin); // Kierrä nuppia //Anna tilaajan numero, sir käyttäjä. soitaToiselleKäyttäjälle(224466, puhelin); //Soittonumero 224466 käyttäjä. callToiselleKäyttäjälle(224466, videopuhelin); //Videokanavan yhdistäminen tilaajalle 224466 Kutsumalla samaa menetelmää käyttäjäobjektissa saimme erilaisia ​​tuloksia. Kutsumenetelmän erityinen toteutus callAnotherUser-menetelmässä valittiin dynaamisesti kutsuvan objektin tietyn tyypin perusteella ohjelman suorituksen aikana. Tämä on polymorfismin tärkein etu - toteutuksen valinta ohjelman suorittamisen aikana. Yllä olevissa puhelinluokan esimerkeissä käytimme metodin ohitusta, tekniikkaa, joka muuttaa perusluokassa määritettyä menetelmän toteutusta muuttamatta menetelmän allekirjoitusta. Tämä on pohjimmiltaan menetelmän korvaus, ja se on uusi aliluokkaan määritetty menetelmä, jota kutsutaan ohjelman suorituksen yhteydessä. Tyypillisesti menetelmää ohitettaessa käytetään @Override-merkintää, joka käskee kääntäjää tarkistamaan ohitettujen ja ohitettavien menetelmien allekirjoitukset. Lopulta Noudata näitä vinkkejä varmistaaksesi, että ohjelmasi tyyli vastaa OOP:n konseptia ja OOP javan periaatteita:
  • korostaa kohteen tärkeimmät ominaisuudet;
  • korostaa yhteisiä ominaisuuksia ja käyttäytymistä sekä käyttää perintöä objekteja luodessaan;
  • käytä abstrakteja tyyppejä kuvaamaan esineitä;
  • Yritä aina piilottaa menetelmät ja kentät, jotka liittyvät luokan sisäiseen toteutukseen.
Tämän postauksen englanninkielinen versio:

(kuten OOP tarkoittaa) on ennen kaikkea ohjelmointiparadigma.
Ohjelmointiparadigma määrittää, kuinka ohjelmoija näkee ohjelman suorittamisen.
OOP-paradigmalle on siis tunnusomaista se, että ohjelmoija näkee ohjelman vuorovaikutteisten objektien joukkona, kun taas esimerkiksi toiminnallisessa ohjelmoinnissa ohjelma esitetään funktiolaskentojen sarjana. Proseduuriohjelmointi tai, kuten sitä oikein kutsutaan, klassinen operatiivinen ohjelmointi, sisältää algoritmin kirjoittamisen ongelman ratkaisemiseksi; tässä tapauksessa lopputuloksen odotettuja ominaisuuksia ei kuvata tai osoiteta. Strukturoitu ohjelmointi noudattaa periaatteessa samoja periaatteita kuin prosessiohjelmointi, johon on lisätty muutamia hyödyllisiä tekniikoita.
Ei-proseduaaliset ohjelmointiparadigmat, joihin sisältyy olio-paradigma, ovat täysin erilaisia.
Gradi Buchan määritelmä kuuluu: " Olio-ohjelmointi on ohjelmointimetodologia, joka perustuu ohjelman esittämiseen kokoelmana objekteja, joista jokainen on tietyn luokan (erityistyypin) toteutus ja luokat muodostavat periytyvyysperiaatteisiin perustuvan hierarkian."
Strukturoitu ja olioohjelmointi perustuu tieteelliseen menetelmään, joka tunnetaan nimellä hajoaminen- menetelmä, joka käyttää ongelman rakennetta ja mahdollistaa yhteisen suuren ongelman ratkaisun jakamisen pienempien ongelmien sarjaksi. OOP:n hajoaminen ei tapahdu algoritmien, vaan ongelman ratkaisemisessa käytettyjen objektien mukaan. Tämä hajoaminen pienentää ohjelmistojärjestelmien kokoa käyttämällä uudelleen yleisiä mekanismeja. Tiedetään, että järjestelmät visuaalinen ohjelmointi tai olio-ohjelmointiperiaatteille rakennetut järjestelmät ovat joustavampia ja kehittyvät helpommin ajan myötä.

OOP:n kehityksen historia on peräisin 60-luvun lopulta. Ensimmäinen oliokieli oli Simula-ohjelmointikieli, joka luotiin tietokonekeskuksessa Norjassa. Kielen tarkoituksena oli mallintaa todellisia tilanteita. Simulan erikoisuus oli, että kielellä kirjoitettu ohjelma järjestettiin ohjelmointiobjekteiksi. Objekteilla oli käskyjä, joita kutsuttiin menetelmiksi ja dataa, jota kutsutaan muuttujiksi; menetelmät ja tiedot määrittelivät kohteen käyttäytymisen. Simulaation aikana kohde käyttäytyi oletuskäyttäytymisensä mukaisesti ja muutti tarvittaessa tietoja kuvastamaan sille osoitetun toiminnon vaikutusta.

Nykyään niitä on riittävästi olio-ohjelmointikielet, joista suosituimmat ovat tällä hetkellä C++, Delphi, Java, Visual Basic,Salama. Mutta lisäksi monilla kielillä, jotka yleensä luokitellaan prosessiparadigmaksi, on myös OOP-ominaisuuksia, jotka voivat työskennellä objektien kanssa. Siten C:n olioohjelmointi on suuri osa ohjelmointia tällä kielellä, sama pätee OOP:ään pythonissa ja monissa muissa strukturoiduissa kielissä.

Kun puhutaan OOP:sta, tulee usein esiin toinen määritelmä - visuaalinen ohjelmointi. Se tarjoaa lisäksi laajan objektiprototyyppien käytön, jotka määritellään objektiluokiksi.
Tapahtumat. Monet visuaaliset ohjelmointiympäristöt toteuttavat objektin - tapahtuman - ominaisuuden (kapseloinnin, polymorfismin ja periytymisen lisäksi). Olio-ohjelmoinnin tapahtumat ovat kyky käsitellä käyttöjärjestelmästä saatuja ns. viestejä (tai tapahtumia). Windows-järjestelmät tai itse ohjelma. Tämä periaate on tyypillinen kaikille ympäristön komponenteille, jotka käsittelevät erilaisia ​​tapahtumia, jotka syntyvät ohjelman suorittamisen aikana. Pohjimmiltaan tapahtuma on jokin toiminto, joka aktivoi objektin normaalin reaktion. Tapahtumana voidaan pitää esimerkiksi hiiren painikkeen napsauttamista, hiiren osoittimen siirtämistä valikon kohdan päälle, välilehden avaamista jne. Järjestys, jossa tietyt toiminnot suoritetaan, määräytyy tarkalleen järjestelmässä tapahtuvien tapahtumien ja esineiden reaktioiden perusteella.
OOP:n luokat ja objektit- erilaisia ​​käsitteitä. OOP:n luokan käsite on tietotyyppi (sama kuin esimerkiksi Real tai String), ja objekti on luokan tietty esiintymä (sen kopio), joka on tallennettu tietokoneen muistiin vastaavan tyyppisenä muuttujana. .
Luokka On rakenteellinen tyyppi tiedot. Luokka sisältää kuvauksen tietokentistä sekä proseduureista ja toiminnoista, jotka toimivat näillä tietokentillä. OOP menetelmä- nämä ovat sellaisia ​​luokkiin liittyviä menettelyjä ja toimintoja.
Luokissa on kenttiä (kuten tietueen tietotyyppi), ominaisuuksia, jotka ovat samankaltaisia ​​kuin kenttiä, mutta niillä on lisäkuvaajia, jotka määrittävät tiedon kirjoittamisen ja lukemisen mekanismit, sekä menetelmiä - aliohjelmia, joiden tarkoituksena on muuttaa luokan kenttiä ja ominaisuuksia.

OOP:n perusperiaatteet

Olio-ohjelmoinnin periaatteita ovat tapahtumien käsittelyn lisäksi kapselointi, periytyminen, alaluokittelu ja polymorfismi. Ne ovat erityisen hyödyllisiä ja tarpeellisia kehitettäessä sovelluksia, jotka ovat replikoitavissa ja helppoja ylläpitää.
Objekti yhdistää menetelmiä ja ominaisuuksia, joita ei voi olla siitä erillään. Siksi, jos objekti poistetaan, sen ominaisuudet ja siihen liittyvät menetelmät poistetaan. Kopioitaessa tapahtuu sama: objekti kopioidaan kokonaisuutena. OOP kapselointi- tämä on kuvattu ominaisuus.

OOP:n periytymisperiaate ja alaluokat

Ehdottomasti kaikki objektit luodaan luokkien perusteella, ja ne perivät näiden luokkien ominaisuudet ja menetelmät. Luokkia voidaan puolestaan ​​luoda muiden luokkien (vanhempien) perusteella, jolloin tällaisia ​​luokkia kutsutaan alaluokiksi (jälkeläisiksi). Alaluokat perivät kaikki emoluokan ominaisuudet ja menetelmät. Lisäksi alaluokalle tai jälkeläiselle luokalle voit määrittää uusia, omia ominaisuuksia ja menetelmiä sekä muuttaa pääluokan menetelmiä. Pääluokan ominaisuuksien ja menetelmien muutoksia seurataan tämän luokan perusteella luoduissa alaluokissa sekä alaluokkien perusteella luoduissa objekteissa. Tästä OOP-perinnössä on kyse.

OOP polymorfismi

Olio-ohjelmoinnissa polymorfismia luonnehditaan objektien vaihdettavuudeksi, joilla on sama käyttöliittymä. Tämä voidaan selittää näin: lapsiluokka perii emoluokan menetelmien ilmentymiä, mutta näiden menetelmien suoritus voi tapahtua eri tavalla, joka vastaa aliluokan erityispiirteitä, eli modifioituna.
Eli jos proseduuriohjelmoinnissa proseduurin tai funktion nimi yksilöi tähän toimintoon tai toimintoon liittyvän suoritetun koodin, niin olioohjelmoinnissa voidaan käyttää samoja menetelmänimiä eri toimien suorittamiseen. Eli saman menetelmän suorittamisen tulos riippuu objektin tyypistä, johon menetelmää sovelletaan.

Sivusto esittelee osittaisen olioohjelmoinnin teorian aloittelijoille ja OOP-esimerkkejä ongelmanratkaisusta. Sivuston OOP-tunnit ovat yksityiskohtaisia ​​algoritmeja tietyn tehtävän suorittamiseksi. Näiden laboratoriotöiden perusteella opiskelija pystyy tulevaisuudessa itsenäisesti ratkaisemaan muita vastaavia ongelmia.
Toivotamme sinulle helppoa ja mielenkiintoista olioohjelmoinnin oppimista!

Olio-ohjelmointi (OOP) muodostaa Javan perustan. Pohjimmiltaan kaikki Java-ohjelmat ovat jossain määrin oliokeskeisiä. Java-kieli liittyy niin läheisesti OOP:hen, että ennen kuin alat kirjoittaa siihen yksinkertaisimpiakin ohjelmia, sinun tulee ensin tutustua OOP:n perusperiaatteisiin. Siksi aloitetaan pohtimalla OOP:n teoreettisia kysymyksiä.

Kaksi tekniikkaa

Kaikki tietokoneohjelmat koostuvat kahdesta osasta: koodista ja tiedosta. Lisäksi ohjelma voidaan käsitteellisesti järjestää sen koodin tai sen datan ympärille. Toisin sanoen joidenkin ohjelmien järjestäminen määräytyy sen mukaan, mitä tapahtuu, kun taas toisten määrää se, mihin vaikuttaa. Ohjelmien luomiseen on kaksi tapaa. Ensimmäinen niistä on ns prosessisuuntautunut malli ja luonnehtii ohjelmaa lineaaristen vaiheiden sarjana (eli koodina). Prosessisuuntautunut malli voidaan katsoa mm koodi, joka vaikuttaa tietoihin. Tätä mallia on käytetty melko menestyksekkäästi proseduurikielissä, kuten C. Mutta kuten luvussa 1 todettiin, tämä lähestymistapa aiheuttaa useita vaikeuksia ohjelmien kasvavan koon ja monimutkaisuuden vuoksi.

Ohjelman monimutkaisuuden kasvun voittamiseksi kehitettiin lähestymistapa, jota kutsutaan olio-ohjelmointi. Olio-ohjelmoinnin avulla voit järjestää ohjelman sen tietojen (eli objektien) ympärille ja joukon hyvin määriteltyjä rajapintoja näiden tietojen kanssa. Olio-ohjelma voidaan luonnehtia tietona, joka ohjaa pääsyä koodiin. Kuten myöhemmin käsitellään, tiedonhallintatoimintojen ulkoistaminen voi tarjota useita organisaation etuja.

Abstraktio

OOP:n tärkeä osa on abstraktio. Ihmisluonto on edustaa monimutkaisia ​​ilmiöitä ja esineitä käyttämällä abstraktiota. Esimerkiksi ihmiset eivät kuvittele autoa kymmenien tuhansien yksittäisten osien kokoelmana, vaan täysin erityisenä esineenä, jolla on oma erityinen käyttäytymisensä. Tämän abstraktion avulla sinun ei tarvitse ajatella auton osien monimutkaisuutta, kun esimerkiksi ajetaan kauppaan. Voit jättää huomioimatta moottorin, vaihteiston ja jarrujärjestelmän yksityiskohdat. Sen sijaan kohdetta voidaan käyttää yhtenä kokonaisuutena.

Hierarkkiset luokitukset ovat tehokas keino soveltaa abstraktiota. Tämä mahdollistaa monimutkaisten järjestelmien semantiikan yksinkertaistamisen ja jakamalla ne paremmin hallittaviin osiin. Ulkoisesti auto näyttää yhdeltä esineeltä. Mutta kun katsot sisään, käy selväksi, että se koostuu useista alajärjestelmistä: ohjaus, jarrut, äänijärjestelmä, turvavyöt, lämmitin, navigaattori jne. Jokainen näistä alajärjestelmistä puolestaan ​​kootaan erikoistuneemmista yksiköistä. Esimerkiksi audiojärjestelmä koostuu radiosta, CD-soittimesta ja/tai äänikasetteista. Kaiken tämän pointti on, että auton (tai minkä tahansa muun monimutkaisen järjestelmän) rakennetta voidaan kuvata käyttämällä hierarkkisia abstraktioita.

Monimutkaisten järjestelmien hierarkkisia abstraktioita voidaan soveltaa myös tietokoneohjelmiin. Abstraation avulla perinteisen prosessisuuntautuneen ohjelman tiedot voidaan muuntaa sen osaobjekteiksi ja prosessin vaiheiden sarja voidaan muuntaa näiden objektien välillä välitetyksi viestijoukoksi. Siten jokainen näistä objekteista kuvaa omaa erityistä käyttäytymistään. Näitä objekteja voidaan pitää konkreettisina kokonaisuuksina, jotka vastaavat niitä ohjaaviin viesteihin selittää tiettyä toimintaa. Tämä on itse asiassa koko OOP:n olemus.

OOP-periaatteet ovat sekä Java-kielen että ihmisen maailmankäsityksen taustalla. On tärkeää ymmärtää, kuinka nämä periaatteet toteutetaan ohjelmissa. Kuten myöhemmin käy ilmi, OOP on toinen, mutta tehokkaampi ja luonnollisempi tekniikka sellaisten ohjelmien luomiseen, jotka selviävät mukana tulevista väistämättömistä muutoksista. elinkaari mikä tahansa suuri ohjelmistoprojekti, mukaan lukien sen suunnittelu, kehittäminen ja kypsyminen. Jos sinulla on esimerkiksi tarkasti määritellyt objektit ja selkeät, luotettavat rajapinnat niihin, voit turvallisesti ja helposti poistaa tai vaihtaa vanhan järjestelmän osia.

OOP:n kolme periaatetta

Kaikki olio-ohjelmointikielet tarjoavat mekanismeja, jotka helpottavat olio-mallin toteuttamista. Näitä mekanismeja ovat kapselointi, perinnöllisyys ja polymorfismi. Katsotaanpa näitä OOP-periaatteita yksitellen.

Kapselointi

Kutsutaan mekanismia, joka yhdistää koodin ja sen käsittelemän datan ja suojaa sekä ulkopuoliselta häiriöltä että väärinkäytöltä kapselointi. Kapselointia voidaan pitää suojakuorena, joka suojaa koodia ja dataa ulkopuolisten muiden koodien satunnaiskäytöltä. Pääsyä koodiin ja tietoihin kuoren sisällä valvotaan tarkasti tarkasti määritellyllä käyttöliittymällä. Jos haluat tehdä todellisen analogian, harkitse automaattivaihteistoa autossa. Se sisältää paljon tietoa autosta, mukaan lukien kiihtyvyyden määrä, ajettavan pinnan jyrkkyys ja vaihdevivun asento. Käyttäjä (tässä tapauksessa kuljettaja) voi vaikuttaa tähän monimutkaiseen kotelointiin vain yhdellä tavalla: liikuttamalla vaihdevipua. Vaihteistoon eivät saa vaikuttaa esimerkiksi suuntavilkut tai tuulilasinpyyhkimet. Siten vaihdevipu on tiukasti määritelty ja käytännössä ainoa liitäntä vaihteiston kanssa. Lisäksi se, mitä vaihteiston sisällä tapahtuu, ei vaikuta sen ulkopuolella oleviin esineisiin. Esimerkiksi vaihteiden vaihtaminen ei sytytä ajovaloja! Toiminto automaattinen vaihto vaihteet ovat kapseloituja, joten kymmenet autonvalmistajat voivat toteuttaa sen miten haluavat. Mutta kuljettajan näkökulmasta kaikki nämä vaihteistot toimivat samalla tavalla. Samanlaista periaatetta voidaan soveltaa ohjelmoinnissa. Vahvuus kapseloitu koodi tarkoittaa, että kaikki tietävät, miten siihen pääsee käsiksi, ja siksi sitä voidaan käyttää toteutusyksityiskohdista riippumatta ja ilman odottamattomien sivuvaikutusten pelkoa.

Ejava-kapseloinnin ydin on luokka. Luokkia käsitellään tarkemmin seuraavissa luvuissa, mutta siihen asti on hyödyllistä antaa niistä ainakin lyhyt kuvaus. Luokka määrittää rakenteen ja käyttäytymisen (data ja koodi), jotka objektijoukot jakavat. Jokainen tietyn luokan objekti sisältää luokan määrittelemän rakenteen ja käyttäytymisen, ikään kuin objekti olisi "valettu" luokan muottiin. Siksi joskus objekteja kutsutaan luokan tapauksia. Siten luokka on looginen rakennelma ja objekti sen fyysinen suoritusmuoto.

Kun luot luokan, määrität koodin ja tiedot, jotka muodostavat luokan. Yhdessä näitä elementtejä kutsutaan jäsenet luokkaa. Erityisesti luokassa määriteltyä dataa kutsutaan vaihtaa jäseniään, tai instanssimuuttujat, ja dataa käyttävä koodi on jäsenmenetelmiä tai yksinkertaisesti menetelmiä.(Mitä Java-ohjelmoijat kutsuvat menetelmät, C/C++-ohjelmoijat soittavat toiminnot) Oikein Java-kielellä kirjoitetuissa ohjelmissa menetelmät määrittelevät, kuinka jäsenmuuttujia käytetään. Tämä tarkoittaa, että luokan käyttäytyminen ja käyttöliittymä määräytyvät sen esiintymän tiedoilla toimivat menetelmät.

Koska luokan tarkoitus on kapseloitua monimutkainen rakenne ohjelmissa on mekanismeja monimutkaisen toteutusrakenteen piilottamiseksi itse luokassa. Jokainen menetelmä tai muuttuja luokassa voidaan merkitä yksityiseksi tai julkiseksi. Avata Luokan käyttöliittymä edustaa kaikkea, mitä luokan ulkopuolisten käyttäjien pitäisi tai voi tietää. Suljettu menetelmiä ja tietoja voidaan käyttää vain koodilla, joka on tietyn luokan jäsen. Siksi mikään muu koodi, joka ei ole tämän luokan jäsen, ei voi käyttää yksityistä menetelmää tai muuttujaa. Luokan yksityiset jäsenet ovat muiden ohjelman osien käytettävissä vain luokan julkisten menetelmien kautta, mikä eliminoi mahdollisuuden laittomiin toimiin. Tämä tietysti tarkoittaa, että julkinen käyttöliittymä on suunniteltava huolellisesti, eikä se saa paljastaa tarpeettomia yksityiskohtia luokan sisäisestä toiminnasta (kuva 1).

Riisi. 1.

Perintö

Prosessia, jolla yksi objekti hankkii toisen ominaisuudet, kutsutaan perinnön. Tämä on erittäin tärkeä OOP:n periaate, koska periytyminen tarjoaa hierarkkisen luokittelun periaatteen. Kuten aiemmin todettiin, suurin osa tiedosta on assimiloitavissa hierarkkisen (eli ylhäältä alas) luokituksen kautta. Esimerkiksi kultainennoutaja kuuluu luokitukseen koirat, joka puolestaan ​​kuuluu luokkaan nisäkkäät, ja se - vielä suurempaan luokkaan eläimet. Ilman hierarkioita jokaisen objektin olisi määriteltävä eksplisiittisesti kaikki ominaisuutensa. Mutta periytymisen ansiosta objektin tulee määrittää vain ne asiat, jotka tekevät siitä erityisen luokassa. Objekti voi periä yleiset attribuutit pääobjektistaan. Siten periytymismekanismin avulla voit tehdä yhdestä objektista yleisemmän tapauksen erikoistapauksen. Tarkastellaan tätä mekanismia yksityiskohtaisemmin.

Yleensä useimmat ihmiset näkevät ympäröivän maailman hierarkkisesti toisiinsa liittyvien esineiden, kuten eläinten, nisäkkäiden ja koirien, muodossa. Jos haluat antaa abstraktin kuvauksen eläimistä, voit sanoa, että niillä on tiettyjä ominaisuuksia: koko, älykkyystaso ja luusto. Eläimillä on myös tiettyjä käyttäytymisominaisuuksia: ne syövät, hengittävät ja nukkuvat. Tämä ominaisuuksien ja käyttäytymisen kuvaus muodostaa määritelmän luokkaa eläimet.

Jos kuvailisimme tarkempaa eläinluokkaa, kuten nisäkkäitä, meidän olisi määriteltävä tarkempia ominaisuuksia, kuten hampaiden ja rintarauhasten tyyppi. Tätä määritelmää kutsutaan alaluokka kuuluvia eläimiä superluokka(vanhempiluokka) nisäkkäät. Ja koska nisäkkäät ovat vain tarkemmin määriteltyjä eläimiä, he periä kaikki eläinten ominaisuudet. Alemman tason alaluokka luokkahierarkia perii jokaisen emoluokkansa kaikki ominaisuudet (kuva 2).

Riisi. 2.

Perinnöllisyys liittyy myös kapseloitumiseen. Jos yksittäinen luokka kapseloi tiettyjä ominaisuuksia, millä tahansa sen alaluokalla on samat ominaisuudet plus kaikki muut, jotka määrittävät sen erikoistumisen (kuva 3). Tämän avainperiaatteen vuoksi olioohjelmien monimutkaisuus lisääntyy aritmeettisessa progressiossa geometrisen etenemisen sijaan. Uusi alaluokka perii kaikkien vanhempien luokkiensa attribuutit, eikä sillä siksi ole arvaamattomia vuorovaikutuksia suuren osan muun järjestelmäkoodin kanssa.

Riisi. 3. Labradoriitti perii täysin kaikkien emoeläinluokkien kapseloidut ominaisuudet

Polymorfismi

Polymorfismi(kreikan sanasta "monia muotoja") on OOP-periaate, joka mahdollistaa saman rajapinnan käytön yhteiseen kanteen luokkaan. Jokainen toimenpide riippuu tietystä tilanteesta. Harkitse esimerkkinä pinoa, joka toimii käänteisenä kauppaluettelona. Oletetaan, että ohjelma vaatii kolmenlaisia ​​pinoja: kokonaislukuarvoja, liukulukujen numeerisia arvoja ja merkkejä. Toteutusalgoritmi jokaiselle näistä pinoista pysyy samana, huolimatta niihin tallennetun datan eroista. Ei-oliosuuntautuneessa kielessä pinon manipulointi vaatisi kolmen erilaisen apuohjelman luomisen eri nimillä. Javassa polymorfismin periaatteen ansiosta voidaan määrittää yhteinen apuohjelma pinon käsittelyyn samoilla yleisillä nimillä.

Yleisemmin polymorfismin periaate ilmaistaan ​​usein lauseella "yksi rajapinta, useita menetelmiä". Tämä tarkoittaa, että on mahdollista kehittää yhteinen rajapinta toisiinsa liittyvien toimintojen ryhmälle. Tämä lähestymistapa vähentää ohjelman monimutkaisuutta, koska määrittämiseen käytetään samaa käyttöliittymää yleinen toimintaluokka. Ja valinta erityistä toimintaa(eli menetelmä) tehdään kunkin tilanteen mukaan ja se on kääntäjän vastuulla. Tämä säästää ohjelmoijaa tekemästä näitä valintoja manuaalisesti. Hänen täytyy vain muistaa yleinen käyttöliittymä ja soveltaa sitä oikein.

Jos jatkamme analogiaa koirien kanssa, voimme sanoa, että koiran hajuaisti on polymorfinen ominaisuus. Jos koira haistaa kissan, se haukkuu ja jahtaa sitä. Ja jos koira haistaa ruokansa, se alkaa vuotaa sylkeä ja ryntää kulhoonsa. Molemmissa tapauksissa toimii sama hajuaisti. Ainoa ero on siinä, mikä tuoksun tarkalleen tuottaa, ts. koiran nenään vaikuttavassa tietotyypissä! Tämä yleinen käytäntö voidaan toteuttaa soveltamalla sitä Java-ohjelman menetelmiin.

Polymorfismin, kapseloinnin ja periytymisen yhdistetty käyttö

Kun polymorfismin, kapseloinnin ja periytymisen periaatteita sovelletaan oikein, ne muodostavat yhdessä ohjelmointiympäristön, joka tukee sellaisten ohjelmien kehittämistä, jotka ovat kestävämpiä ja skaalautuvampia kuin prosessisuuntautuneessa mallissa. Huolellisesti suunniteltu luokkahierarkia tarjoaa vahvan perustan koodin uudelleenkäytölle, jonka kehittämiseen ja testaamiseen olet käyttänyt aikaa ja vaivaa. Kapseloinnin avulla voit palata aiemmin luotuihin toteutuksiin rikkomatta koodia, joka riippuu avoin käyttöliittymä sovelluksessa käytetyt luokat. Ja polymorfismin avulla voit luoda selkeää, käytännöllistä, luettavaa ja vakaata koodia.

Aiemmin annetuista kahdesta esimerkistä oikea elämä Esimerkki autoista havainnollistaa paremmin OOP:n ominaisuuksia. Vaikka esimerkki koirista sopii varsin hyvin OOP:n pohtimiseen perinnön näkökulmasta, autoesimerkillä on enemmän yhteistä ohjelmien kanssa. Ratin taakse istuminen erilaisia ​​tyyppejä(alaluokissa) kaikki kuljettajat käyttävät perintöä. Olipa kyseessä koulubussi, henkilöauto, urheiluauto tai perheen tila-auto, kaikki kuljettajat löytävät ja käyttävät helposti ohjauspyörää, jarruja ja kaasupoljinta. Vaihdevivun pientä puuhailua useimmat voivat jopa ymmärtää manuaalivaihteiston ja automaattivaihteiston eroja, kunhan he ymmärtävät selkeästi näiden kahden yhteisen emoluokan, vaihteistojärjestelmän.

Autoja käyttäessään ihmiset ovat jatkuvasti vuorovaikutuksessa niiden kapseloitujen ominaisuuksien kanssa. Jarru- ja kaasupolkimet kätkevät vastaavien esineiden uskomattoman monimutkaisuuden käyttöliittymän taakse niin yksinkertaisen, että näiden kohteiden hallitsemiseksi tarvitsee vain painaa poljinta jalallasi! Moottorin erityinen toteutus, jarrutyyppi ja rengaskoko eivät vaikuta siihen, miten ne vaikuttavat poljinluokan määrittämiseen.

Lopuksi, polymorfismi heijastaa selvästi autonvalmistajien kykyä tarjota laaja valikoima vaihtoehtoja olennaisesti samalle ajoneuvolle. Ajoneuvo voidaan varustaa esimerkiksi lukkiutumattomilla tai perinteisillä jarruilla, ohjaustehostimella tai hammastanko-ohjauksella sekä 4-, 6- tai 8-sylinterisillä moottoreilla. Mutta joka tapauksessa sinun täytyy painaa jarrupoljinta pysähtyäksesi, kääntää ohjauspyörää kääntyäksesi ja painaa kaasupoljinta, jotta auto liikkuu nopeammin. Samaa käyttöliittymää voidaan käyttää monenlaisten toteutusten ohjaamiseen.

Kuten näette, kapseloinnin, periytymisen ja polymorfismin periaatteiden yhdistetyn soveltamisen ansiosta yksittäisistä osista voidaan tehdä esine, jota kutsutaan autoksi. Sama koskee tietokoneohjelmat. OOP-periaatteet mahdollistavat yhtenäisen, luotettavan, ylläpidettävän ohjelman rakentamisen useista erillisistä osista.

Kuten tämän osan alussa todettiin, jokainen Java-ohjelma on oliopohjainen. Tarkemmin sanottuna jokainen Hajava-ohjelma soveltaa kapseloinnin, periytymisen ja polymorfismin periaatteita. Ensi silmäyksellä saattaa vaikuttaa siltä, ​​että kaikki nämä periaatteet eivät esiinny tämän luvun loppuosassa ja useissa myöhemmissä luvuissa annetuissa lyhyissä esimerkkiohjelmissa, mutta ne ovat niissä kuitenkin läsnä. Kuten myöhemmin käy ilmi, monet Java-kielen ominaisuudet ovat osa sisäänrakennettuja luokkakirjastoja, jotka hyödyntävät laajasti kapseloinnin, periytymisen ja polymorfismin periaatteita.