Kotlin-liitännät (esimerkkien kanssa)

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 interfacemää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 = 23kä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.

Mielenkiintoisia artikkeleita...