Rajapinta (Interface)

Rajapinta

Rajapinta (Interface) on viittaustyyppi. Sitä käytetään määrittämään ja ryhmittämään metodeita, joita voi toisistaan riippumattomat luokat toteuttavat. Rajapinta on ikään kuin "sopimus" tai "lupaus", että rajapinnan toteuttava luokkaa lupaa toteuttaa rajapinnan määrittelemän toiminnallisuuden. Sen avulla saadaan tyyppiyhtenevyys erillisten ja erilaisten luokkien välillä. Luokka voi toteuttaa useita rajapintoja. Koska C#:ssa ei ole moninperintää, niin rajapintojen avulla voidaan luokalla toteuttaa moniperinnän tapaan useampaa toiminallisuutta.

Rajapinta muistuttaa luokkaa, mutta sisältää vain ja ainoastaan:

metodien nimiä
ominaisuuksien nimiä
indeksoijia

Rajapinta ei sisällä ollenkaan koodia eikä kenttiä!
Rajapinta nimetään aina isolla I-kirjaimella, esim siis IAnimal.

Rajapinnan määrittely

Rajapinnan määrittelyn yhteydessä ei käytetä class- tai abstract-avainsanoja, vaan interface-avainsanaa. Rajapinta voi sisältää ominaisuuksia ja toimintoja eli metodeja. Tosin yhdelläkään metodilla ei saa olla toteutusta (esittelyssä ei käytetä abstract-avainsanaa). Rajapinnan toteuttavan luokan on siis toteutettava kaikki sen toteuttaman rajapinnan määrämät metodit. Rajapinnan nimessä ensimmäisenä kirjaimena käytetään I-kirjainta.

Esimerkki

Tutkitaan asiaa esimerkin valossa. Tehdään IAnimal-liittymä, jossa on esitelty Name-ominaisuus ja Draw()-metodi. Huomaa, että metodilla ei ole toteutusta eli {}-merkkejä rivillä 4.


    

Nyt siis kaikilla luokilla, jotka haluavat toteuttaa IAnimal-rajapinnan tulee olla toteutettuna Name-ominaisuus ja Talk()-metodi eli kuinka juuri kyseessä oleva "eläin" puhuu! Eli rajapinta ikäänkuin kertoo, että IAnimal-rajapinnan toteuttaviin luokkiin tulee toteuttaa Name-ominaisuus ja Talk()-metodi. Tämän jälkeen ohjelmat, jotka käyttävät IAnimal-rajapintoja toteuttavia luokkia voivat luottaa siihen, että luokilla on varmasti Name-ominaisuus ja se osaa puhua Talk()-metodilla. Kuhinkin luokkaan on toteutettu oma, muista riippumaton itsenäinen toteutus edellä mainituista.

Toteutetaan Cat- ja Dog-luokat, jotka toteuttavat IAnimal-liittymän, eli siis ovat sen tyyppisiä olioita.


    

    

Nyt Cat- ja Dog-luokkia voidaan käyttää seuraavasti:


	

Esimerkki kahden erilaisen luokan yhteisestä rajapinnasta

Rajapinnan hyöty tulee esille varsinkin kuin meillä on tarkoitus saada samanlaista toiminnallisuutta kahdelle erilaisella luokalle. Edellinen esimerkki olisi voitu toteuttaa ilman rajapintaa myös abstract-luokalla tai periyttämällä kantaluokasta Animal Cat- ja Dog-luokat. Mutta jos ajatellaan reaalimaailman tilannetta miten eri tavoin ja millä välineillä/laitteille voimme tehdä muistiinpanoja. Voimme tehdä muistiinpanoja seuraaville välineille: paperille, muistioon, kännykkään, tietokoneelle jne. Nyt on vaikea keksiä mikä voisi olla yhteinen kantaluokka paperille ja kännykälle. Sen sijaan määrittämällä rajapinnan ICanMakeANote, ja määrittämällä sen paperi ja kännykkä luokille voimme varmistaa, että molemmat luokat toteuttavat kyseisen metodin.

Esimerkissä on määritelty yksinkertainen rajapinta ICanMakeANote, jonka kumpikin luokista Tablet ja Paper toteuttavat.


	

 

Miten rajapintoja käytetään ja mikä oli ero perintään?

Semanttisestikin ero on: perittäessä peritään kantaluokan ominaisuudet ja metodit perittävälle luokalle. Kun taas rajapintaa käytettäessä "luvataan" luokan toteuttavan rajapinnan "vaatimat" toteutukset, eli ei peritä mitään, vaan luvataan toteuttaa.

Erona perintään on se, että määriteltäessä luokka käyttämään rajapintaa saa vain rajapinnan ja kaikki metodit joutuu toteuttamaan itse. Perintä tuo mukanaan jo mahdollisesti joukon toteutuksiakin sekä kantaluokan ominaisuudet ovat olemassa.

Rajapinta on sopimus. Se kertoo, millaisia metodeja rajapinnan toteuttava olio tarjoaa käytettäväksi, ja millaisia metodeja olion käyttäjä voi kutsua. Rajapinta piilottaa toteutuksen, eli ei ole tarve kysellä, eikä tulisi olla tarve kysellä, mikä olio ja miten toteuttaa rajapinnan metodit.

Rajapinta voi periä toisen rajapinnan, mutta luokka voi vain toteuttaa rajapinnan. Perintä ja rajapinta ovat käsitteinä siten vertailukelvottomia, toinen on kohde, toinen operaatio. Rajapinnan perintä eroaa luokan perinnästä siten, että rajapinnan perinnässä ei tule toteutuksia mukana, kun taas luokan perinnässä ne tulevat.

Milloin käyttää abstract ja milloin interface?

check_circle Abstract class: käytetään silloin, kun on tiedossa vain osa toteutuksesta ja loppu osa toteutuksesta jää perivän luokan vastuulle toteuttaa.

check_circle Interface: käytetään silloin, kun halutaan liittymän toteuttaman luokan toteuttaa kaikki sen määrittämät toiminnot.

Yhteenveto

Rajapinta on tärkeä osa olio-ohjelmointia, varsinkin kielissä, joissa ei ole moniperintää kuten C#:ssa ja Javassa. Rajapinnan avulla tavallaan "kierretään" moniperintää ja pakotetaan aliluokat tekemään rajapintojen määräämiä temppuja. Rajapintojen toteuttamille luokille saadaan varmistettua helposti tyyppi-yhteneväisyys.

Lisätietoa

Interfaces (C# Programming Guide)