Kotlin接口

举报
yd_221104950 发表于 2020/12/03 00:37:58 2020/12/03
【摘要】 1.概述 Kotlin接口即可以有抽象方法,也可以有实现了的方法。接口与抽象类的区别在于接口不能存在状态。接口还可以有属性,不过这些属性只能是抽象的,或者提供访问器的实现。Kotlin的接口与Java的类似,也是可以多继承的。 接下来我们来看年Kotlin如何定义接口,以及多继承情况下如何解决冲突和Kotlin中的属性有何特别。 2.定义 Kotlin接口与Jav...

1.概述

Kotlin接口即可以有抽象方法,也可以有实现了的方法。接口与抽象类的区别在于接口不能存在状态。接口还可以有属性,不过这些属性只能是抽象的,或者提供访问器的实现。Kotlin的接口与Java的类似,也是可以多继承的。
接下来我们来看年Kotlin如何定义接口,以及多继承情况下如何解决冲突和Kotlin中的属性有何特别。

2.定义

Kotlin接口与Java接口定义一样也是用interface 关键字定义。接口中的方法可以是抽象或已实现了的,如:

interface MyInterface{
	fun bar()
	fun foo(){
		// optional body	
	}
}		

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2.接口实现

类或对象都可以实现一个或多个接口。对象我们以后再讨论。现在来看类是如何实现接口的,类只需要实现抽象的方法即可:

class Child: MyInterface{
	override fun bar(){
		// body
	}
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

3.接口中的属性

你可以在接口中定义属性。接口中声明的属性可以是抽象的,或者它提供访问器的实现。在接口在声明的属性不能有返回字段(backing field),因此在接口中声明的访问器不能引用它们。

interface MyInterface{
	val prop:Int // 抽象的
	val propertyWithImplementation: String
		get() = "foo"  // 提供访问器实现
	fun foo(){
		print(prop)
	}
}
class Child: MyInterface{
	override val prop:Int = 29
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

4.多继承产生的冲突

类是可以继承多个接口的,但是这些接口都有相同方法的实现,那么就会造成引用冲突,可以使用super<接口名>.的方式,明确调用哪个接口里实现的方法,这样就不会产生歧义。

interface A { fun foo(){// 已实现的 Log.i("Man","A") } fun bar() // 抽象的
}
package com.example.demo

import android.util.Log

interface B { fun foo(){// 已实现的 Log.i("Man","B") } fun bar(){// 已实现的 Log.i("Man","Bar") }
}

// D继承了接口A、B
class D:A,B { override fun foo() { super<A>.foo() super<B>.foo() } override fun bar() { super.bar() }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

接口A、B实现了foo()方法,因此D实例调用这个方法时,一定会引发冲突,所以Kotlin要求子类必须重新实现这个方法。当D实例再调用时就是调自己的,就不会引发歧义了。如果要调用接口中那些实现了的方法,如果使用关键字super加限定词(就是接口名)。如果所示。

如果两个接口有同名的方法,如上例中的bar(),一个实现了,另一个没有实现的情况,就不会造成冲突,如果要调用那个在接口中已实现的方法,直接用super就可以,不需要加限定词,加了还会提示你说多余呢。为什么不用呢?因为只有一个接口实现了,引用不会存在歧义。

5.属性的使用问题

接口中的属性不能有初始化器,说白了就是不能初始化,如下面就是报错的:

interface A { var age: Int = 44 // 错误!错误!错误!属性的初始化器不能出现在接口中 }

  
 
  • 1
  • 2
  • 3

顺便说一句,初始化器就是等号右边的表达式。接口中的属性可以有访问器,即gettersetter,但是它们不能使用返回字段field:

interface A { var age: Int set(value){ field = 9999  // 错误!错误!错误! field这个字段在接口中是不可用的 } var count: Int get() = 999  // 错误!错误!错误! field这个字段在接口中是不可用的,正常情况,get会有field字段返回的 // 以下这个是OK的,子类都无须再实现这个属性,同时这个属性也不能再赋新值,因为field字段在此处不能用,goods永远是666 var goods: Int get() = 666 set(value) {}

 }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

实现接口的属性有两个方法,一是直接赋值,即用初始器,二定义访问器settergetter:

interface A { var age: Int
}

class D:A { override var age: Int get() = 5 set(value) {} // 没有返回字段field,因此不用初始化器
}
或者
class D:A {
	// 使用默认的setter/getter override var age: Int = 8
 }

// 如果setter方法有返回字段field,那么必须用初始化器
class D:A { override var age: Int = 8 set(value){ field = value+1 }
 }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

文章来源: blog.csdn.net,作者:WongKyunban,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/weixin_40763897/article/details/107623810

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。