Tässä artikkelissa opit rajapinnoista ja siitä, miten se toteutetaan Kotlinissa esimerkkien avulla.
Kotlin-rajapinnat ovat samanlaisia kuin Java 8: n rajapinnat. Ne voivat sisältää abstraktien menetelmien määritelmiä sekä ei-abstraktien menetelmien toteutuksia. Ne eivät kuitenkaan voi sisältää mitään tilaa.
Merkitys, rajapinnalla voi olla ominaisuus, mutta sen on oltava abstrakti tai sen on tarjottava käyttöoikeustoteutuksia.
Suositeltava lukeminen: Kotlinin abstrakti luokka
Kotlinin abstraktit luokat ovat samanlaisia kuin käyttöliittymä yhdellä tärkeällä erolla. Ei ole pakollista, että abstraktin luokan ominaisuudet ovat abstrakteja tai tarjoavat lisäsovellustoteutuksia.
Kuinka määritellä käyttöliittymä?
Avainsanalla interface
määritetään rajapinnat Kotlinissa. Esimerkiksi,
käyttöliittymä MyInterface (var test: String // abstrakti ominaisuus hauska foo () // abstrakti menetelmä hauska hei () = "Hei siellä" // menetelmä oletustoteutuksella)
Tässä,
- luodaan käyttöliittymä MyInterface.
- käyttöliittymässä on abstrakti ominaisuuskoe ja abstrakti menetelmä
foo()
. - käyttöliittymässä on myös ei-abstrakti menetelmä
hello()
.
Kuinka käyttöliittymä otetaan käyttöön?
Näin luokka tai esine voi toteuttaa käyttöliittymän:
käyttöliittymä MyInterface (val test: Int // abstrakti ominaisuus hauska foo (): String // abstrakti menetelmä (palauttaa merkkijono) hauska hei () (// menetelmä oletustoteutuksella // body (valinnainen))) luokka InterfaceImp: MyInterface (ohita val-testi: Int = 25 ohittaa hauskan foo () = "Lol" // muu koodi)
Tässä luokan InterfaceImp toteuttaa MyInterface-käyttöliittymän.
Luokka ohittaa foo()
rajapinnan abstraktit jäsenet (testattavat ominaisuudet ja menetelmät).
Esimerkki: Kuinka käyttöliittymä toimii?
interface MyInterface ( val test: Int fun foo() : String fun hello() ( println("Hello there, pal!") ) ) class InterfaceImp : MyInterface ( override val test: Int = 25 override fun foo() = "Lol" ) fun main(args: Array) ( val obj = InterfaceImp() println("test = $(obj.test)") print("Calling hello(): ") obj.hello() print("Calling and printing foo(): ") println(obj.foo()) )
Kun suoritat ohjelmaa, tulos on:
testi = 25 Soittaminen hei (): Hei kaveri! Soittaminen ja tulostaminen foo (): Lol
Kuten edellä mainittiin, rajapinnalla voi olla myös ominaisuus, joka tarjoaa pääsyn toteutuksen. Esimerkiksi,
interface MyInterface ( // property with implementation val prop: Int get() = 23 ) class InterfaceImp : MyInterface ( // class body ) fun main(args: Array) ( val obj = InterfaceImp() println(obj.prop) )
Kun suoritat ohjelmaa, tulos on:
23
Tällöin rekvisiitta ei ole abstrakti. Se on kuitenkin voimassa käyttöliittymän sisällä, koska se tarjoaa käyttöönoton Accessorille.
Et kuitenkaan voi tehdä jotain, kuten val prop: Int = 23
käyttöliittymän sisällä.
Kahden tai useamman käyttöliittymän toteuttaminen luokassa
Kotlin ei salli todellista moniperintöä. On kuitenkin mahdollista toteuttaa kaksi tai useampia rajapintoja yhdessä luokassa. Esimerkiksi,
interface A ( fun callMe() ( println("From interface A") ) ) interface B ( fun callMeToo() ( println("From interface B") ) ) // implements two interfaces A and B class Child: A, B fun main(args: Array) ( val obj = Child() obj.callMe() obj.callMeToo() )
Kun suoritat ohjelmaa, tulos on:
Liitännästä A Liitännästä B
Ylivoimaisten ristiriitojen ratkaiseminen (monikäyttöinen käyttöliittymä)
Oletetaan, että kahdella rajapinnalla (A ja B) on ei-abstrakti menetelmä samalla nimellä (sanotaan callMe()
menetelmä). Olet toteuttanut nämä kaksi rajapintaa luokassa (sanotaan C). Jos nyt kutsut callMe()
menetelmää luokan C objektilla, kääntäjä heittää virheen. Esimerkiksi,
interface A ( fun callMe() ( println("From interface A") ) ) interface B ( fun callMe() ( println("From interface B") ) ) class Child: A, B fun main(args: Array) ( val obj = Child() obj.callMe() )
Tässä on virhe:
Error:(14, 1) Kotlin: Class 'C' must override public open fun callMe(): Unit defined in A because it inherits multiple interface methods of it
To solve this issue, you need to provide your own implementation. Here's how:
interface A ( fun callMe() ( println("From interface A") ) ) interface B ( fun callMe() ( println("From interface B") ) ) class C: A, B ( override fun callMe() ( super.callMe() super.callMe() ) ) fun main(args: Array) ( val obj = C() obj.callMe() )
Now when you run the program, the output will be:
From interface A From interface B
Here, explicit implementation of callMe()
method is provided in class C.
class C: A, B ( override fun callMe() ( super.callMe() super.callMe() ) )
The statement super.callMe()
calls the callMe()
method of class A. Similarly, super.callMe()
calls the callMe()
method of class B
.