I den här artikeln lär du dig om gränssnitt och hur du implementerar det i Kotlin med hjälp av exempel.
Kotlin-gränssnitt liknar gränssnitt i Java 8. De kan innehålla definitioner av abstrakta metoder samt implementeringar av icke-abstrakta metoder. De kan dock inte innehålla något tillstånd.
Betydelse, gränssnitt kan ha egendom men det måste vara abstrakt eller måste tillhandahålla accessorimplementeringar.
Rekommenderad läsning: Kotlin Abstract Class
Abstrakta klasser i Kotlin liknar gränssnittet med en viktig skillnad. Det är inte obligatoriskt för egenskaper i en abstrakt klass att vara abstrakta eller tillhandahålla accessorimplementeringar.
Hur definierar man ett gränssnitt?
Nyckelord interface
används för att definiera gränssnitt i Kotlin. Till exempel,
gränssnitt MyInterface (var test: String // abstrakt egendom kul foo () // abstrakt metod kul hej () = "Hej där" // metod med standardimplementering)
Här,
- ett gränssnitt MyInterface skapas.
- gränssnittet har ett abstrakt egenskapstest och en abstrakt metod
foo()
. - gränssnittet har också en icke-abstrakt metod
hello()
.
Hur implementerar man gränssnitt?
Så här kan en klass eller ett objekt implementera gränssnittet:
gränssnitt MyInterface (val test: Int // abstrakt egendom kul foo (): String // abstrakt metod (returnerar String) kul hej () (// metod med standardimplementering // body (valfritt))) klass InterfaceImp: MyInterface (åsidosätt val test: Int = 25 åsidosätta fun foo () = "Lol" // annan kod)
Här implementerar en klass InterfaceImp MyInterface-gränssnittet.
Klassen åsidosätter abstrakta medlemmar (testegenskap och foo()
metod) i gränssnittet.
Exempel: Hur fungerar gränssnittet?
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()) )
När du kör programmet blir resultatet:
test = 25 Ringer hej (): Hej, kompis! Ringa och skriva ut foo (): Lol
Som nämnts ovan kan ett gränssnitt också ha en egenskap som ger implementering av accessor. Till exempel,
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) )
När du kör programmet blir resultatet:
23
Här är prop inte abstrakt. Det är dock giltigt i gränssnittet eftersom det ger implementering för accessor.
Du kan dock inte göra något som val prop: Int = 23
i gränssnittet.
Implementera två eller flera gränssnitt i en klass
Kotlin tillåter inte sant multipelarv. Det är dock möjligt att implementera två eller flera gränssnitt i en enda klass. Till exempel,
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() )
När du kör programmet blir resultatet:
Från gränssnitt A Från gränssnitt B
Lösa tvingande konflikter (flera gränssnitt)
Antag att två gränssnitt (A och B) har en icke-abstrakt metod med samma namn (låt oss säga callMe()
metoden). Du implementerade dessa två gränssnitt i en klass (låt oss säga C). Nu, om du ringer till callMe()
metoden med hjälp av objektet i klass C, kommer kompilatorn att kasta fel. Till exempel,
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() )
Här är felet:
Fel: (14, 1) Kotlin: Klass 'C' måste åsidosätta offentlig öppen rolig callMe (): Enhet definierad i A eftersom den ärver flera gränssnittsmetoder för den
För att lösa problemet måste du ange din egen implementering. Här är hur:
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() )
Nu när du kör programmet blir resultatet:
Från gränssnitt A Från gränssnitt B
Här callMe()
ges uttrycklig implementering av metod i klass C.
klass C: A, B (åsidosätta fun callMe () (super.callMe () super .callMe ()))
Uttalandet super.callMe()
kallar callMe()
metoden för klass A. På samma sätt kallar den metoden för klass .super.callMe()
callMe()
B