Peruskäsitteitä

Rajapinta (Interface)

Rajapinta 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ä ja
- 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 voivat 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.


	

 

FAQ

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

Semanttisestikin on ero: 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?

When should we use Interfaces and Abstract class
Interface: When we only need to enforce a contract. Whoever will implement this interface will provide an implementation of the methods.
Abstract class: When we need to implement a base type that knows how to implement some part of the abstraction i.e. partial implementation and the other/remaining part of the abstraction cannot be implemented by this class. It leaves the responsibility of implementing remaining methods to the classes deriving from this class.

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)