Kotlin汇总3-接口,可见作用域,扩展,数据类,密封类
来源:互联网 发布:滁州学院网络电视台 编辑:程序博客网 时间:2024/05/01 06:30
1.接口
kotlin的接口比较像Java8,可以有实现的方法
interface MyInterface { fun bar() fun foo() { // optional body }}
接口中的属性可以是抽象的,也可以是提供实现的。
interface MyInterface { val prop: Int // abstract val propertyWithImplementation: String //实现的属性 get() = "foo" fun foo() { print(prop) }}
另外需要注意如果一个类同时实现两个接口,恰好这两个接口都有同一个同样的方法,那么这个类,必须有自己的实现方式,这是Kotlin为了避免冲突的解决方法。
interface A { fun foo() { print("A") } fun bar()}interface B { fun foo() { print("B") } fun bar() { print("bar") }}class C : A { override fun bar() { print("bar") }}class D : A, B { override fun foo() { super<A>.foo() super<B>.foo() } override fun bar() { super<B>.bar() }}
2.可见作用域修饰符
kotlin有四种可见作用域修饰符:public,private,internal,protected,其中public是默认的,这和java的package可见作用域是默认的不一样。
- private 是 class类内可见
- public 是任何地方可见
- protected是private+子类可见
- internal 是 module可以见,这个module包括:intellij module, maven/gradle project, 一个ant task的文件集
3. 扩展
扩展就像装饰者模式,不需要继承,给类增加新功能。
fun MutableList<Int>.swap(index1: Int, index2: Int) { val tmp = this[index1] // 'this' corresponds to the list this[index1] = this[index2] this[index2] = tmp}
一般写法是类名<泛型>.方法,所以你可以理解为static调用的方式。
open class Cclass D: C()fun C.foo() = "c"fun D.foo() = "d"fun printFoo(c: C) { println(c.foo())}printFoo(D())
上面的结果是打印c,因为扩展,它依赖于函数定义时传递的类型(如上是C),而不是运行时传递的类型(如上是D)
class C { fun foo() { println("member") }}fun C.foo() { println("extension") }
如果执行c.foo(),那么结果会是member,就是说如果扩展了同样的方法(包括返回类型,方法名,参数名),那么实际上这个扩展是没有意义的。
但是如果增加了一个覆载的方法就不一养
class C { fun foo() { println("member") }}fun C.foo(i: Int) { println("extension") }
如果执行c.foo(1), 结果会打印extension,因为扩展了C类中没有的方法,因而这个方法是有效地。
而且还有扩展属性
val <T> List<T>.lastIndex: Int get() = size - 1
但是需要注意属性扩展只能使用set/get,而不能直接初始化,比如下面代码是错误的
val Foo.bar = 1 // error: initializers are not allowed for extension properties
一般情况下扩展会应用到top-level
package foo.barfun Baz.goo() { ... }
也可以定义到类里作为成员函数
class D { fun bar() { ... }}class C { fun baz() { ... } fun D.foo() { bar() // calls D.bar baz() // calls C.baz } fun caller(d: D) { d.foo() // call the extension function }}
在扩展里调用它所在类的方法需要如下(this@C)
class C { fun D.foo() { toString() // calls D.toString() this@C.toString() // calls C.toString() }
扩展的目的是为了简化代码如下:
// JavaCollections.swap(list, Collections.binarySearch(list, Collections.max(otherList)), Collections.max(list))//kotlin扩展简化后,代码可阅读性也提高了// Javalist.swap(list.binarySearch(otherList.max()), list.max())
3.数据类
有时候定义一个类仅仅是为了使用它的数据,那么可以定义数据类
data class User(val name: String, val age: Int) // 使用data关键字
然后编译器会帮我们创建好equals/hashcode, toString(),copy方法
fun copy(name: String = this.name, age: Int = this.age) = User(name, age) val jack = User(name = "Jack", age = 1)val olderJack = jack.copy(age = 2)
4.密封类
密封类是为了维护严格的类层次关系。使用sealed关键字修饰,密封类可以有子类,但是它和它的子类都必须在一个kotlin文件中声明.
sealed class Exprdata class Const(val number: Double) : Expr()data class Sum(val e1: Expr, val e2: Expr) : Expr()object NotANumber : Expr()fun eval(expr: Expr): Double = when (expr) { is Const -> expr.number is Sum -> eval(expr.e1) + eval(expr.e2) NotANumber -> Double.NaN}
- Kotlin汇总3-接口,可见作用域,扩展,数据类,密封类
- Kotlin最简单的入门教程——可见性修饰符,扩展,数据类,密封类
- [kotlin系列] (s2_3)扩展、数据类、密封类
- Kotlin(2.7)密封类
- Kotlin——数据类和密封类
- Kotlin Reference (九) 抽象类、密封类
- Kotlin-14.密封类(sealed class)
- Kotlin学习笔记(三)---Kotlin密封类
- 学习kotlin第九天_数据类、枚举类、密封类、嵌套类
- Kotlin学习笔记(七)数据类,密封类,嵌套类,内部类,枚举类
- Kotlin学习(四)—— 类和对象,继承,覆盖,抽象类,属性和字段,接口,可见性修饰符,扩展
- Kotlin编程之伴生对象,抽象类,密封类
- Kotlin 官方学习教程之密封类与泛型
- C# 中的接口和密封类
- 密封类
- C#密封类、密封方法
- 密封类和密封方法
- Kotlin-属性-接口-修饰符-数据类
- java使用poi读取excel文档的一种解决方案
- java--HttpClient的使用
- 安卓大图加载-自定义view
- OpenCV学习笔记(12)canny 边缘检测小程序
- unity5 的 standard assets可以单独下载
- Kotlin汇总3-接口,可见作用域,扩展,数据类,密封类
- PostgreSQL中表名、字段名大小写问题
- 字符集与编码方式
- mysql删除重复数据
- 【PMP】学习笔记20170601
- 几种不同的log4j创建方式
- github使用教程【适用小白】
- tomcat虚拟目录自定义404错误页面
- 日志存储介绍