文章目录
Kotlin 基本语法
资料
https://book.kotlincn.net/text/basic-syntax.html
https://kotlinlang.org/docs/inheritance.html#overriding-rules
代码
https://gitee.com/hellosunshine/kotlin_study.git
输出
fun main(args: Array<String>) {
println(args.contentToString())
print("Hello")
}
函数
fun main() {
print("sum of 3 and 5 is")
println(sum01(3, 5))
println(sum(3, 5))
printSum(-1, 8)
}
fun sum01(a: Int, b: Int): Int {
return a + b
}
fun sum(a: Int, b: Int) = a + b
fun printSum(a: Int, b: Int) {
println("sum of $a and $b is ${a + b}")
}
变量
var x = 0
fun main() {
val a: Int = 1
val b = 2
val c: Int
c = 3
println("a = $a, b = $b, c = $c")
// var x = 5
// x += 1
// println("x = $x")
val PI = 3.14
println("x = $x; PI = $PI")
incrementX()
println("incrementX()")
println("x = $x; PI = $PI")
}
fun incrementX() {
x += 1
}
类与实例
- 普通类
class Shape
class Rectangle(var height: Double, var length: Double) {
var perimeter = (height + length) * 2
}
fun main() {
val rectangle = Rectangle(5.0, 2.0)
println("The perimeter is ${rectangle.perimeter}")
}
- 继承类 定义为 open class
//open为继承
open class Shape
class Rectangle(var height: Double, var length: Double) : Shape() {
var perimeter = (height + length) * 2
}
if表达式
fun main() {
println("max of 0 and 42 is ${maxOf(0, 1)}")
}
fun maxOf(a: Int, b: Int) = if (a > b) a else b
for,while循环
fun main() {
val items = listOf("apple", "banana", "kiwifruit")
for (item in items) {
println(item)
}
for (index in items.indices) {
println("item at $index is ${items[index]}")
}
var index = 0
while (index < items.size) {
println("item at $index is ${items[index]}")
index++
}
}
when表达式
fun describe(obj: Any): String =
when (obj) {
1 -> "One"
"Hello" -> "Greeting"
is Long -> "Long"
!is String -> "Not a string"
else -> "Unknown"
}
fun main() {
println(describe(1))
println(describe("Hello"))
println(describe(1000L))
println(describe(2))
println(describe("other"))
}
range(区间)
val x = 10
val y = 9
//in监测数字是否在执行区域内
if(x in 1..y+1) {
println("fits in range")
}
//!in监测数据不在范围内
val list = listOf("a", "b", "c")
if(-1 !in 0..list.lastIndex) {
println("-1 is out of range")
}
if(list.size !in list.indices) {
println("list size is out of valid list indices range, too")
}
数列迭代
for (x in 1..5) {
print(x)
}
println()
for (x in 1..10 step 2) {
print(x)
}
println()
for (x in 9 downTo 0 step 3) {
print(x)
}
集合
fun main() {
//集合迭代
val items = listOf("apple", "banana", "kiwifruit")
for (item in items) {
println(item)
}
//in判断是否在集合内
when {
"orange" in items -> println("juicy")
"apple" in items -> println("apple is fine too")
}
//过滤排序映射
val fruits = listOf("banana", "avocado", "apple", "kiwifruit")
fruits.filter { it.startsWith("a") }
.map { it.uppercase() }
.sortedBy { it }
.forEach { println(it) }
}
空值检测
fun printProduct(arg1: String, arg2:String) {
val x = parseInt(arg1)
val y = parseInt(arg2)
if(x != null && y != null) {
println(x * y)
} else {
println("'$arg1' or '$arg2' is not a number")
}
// if(x == null) {
// println("Wrong number format in arg1: '$arg1'");
// }
// if(y == null) {
// println("Wrong number format in arg2: '$arg2'");
// }
}
fun main() {
printProduct("6", "7")
printProduct("a", "7")
printProduct("a", "b")
}
类型检测与自动类型转换
fun getStringLength(obj: Any): Int? {
// if (obj is String) {
// return obj.length
// }
// return null;
if(obj !is String) {
return null;
}
//obj自动转换为String
return obj.length;
// if (obj is String && obj.length > 0) {
// return obj.length
// }
// return null;
}
fun main() {
fun printLength(obj: Any) {
println("Getting the length of '$obj'. Result: ${getStringLength(obj) ?: "Error: The object is not a string"}")
}
printLength("Incomprehensibility")
printLength(1000)
printLength(listOf(Any()))
}
kotlin习惯用法
package com.example.kotlinstudy.customUsage
import android.os.Build
import androidx.constraintlayout.solver.widgets.Rectangle
import java.io.File
import java.lang.ArithmeticException
import java.lang.IllegalArgumentException
import java.lang.IllegalStateException
import java.math.BigDecimal
import java.nio.file.Files
import java.nio.file.Paths
//创建DTO
data class Customer(val name: String, val email: String)
//函数的默认参数
fun foo(a: Int = 0, b: String = "") {}
//过滤list
val list = listOf<Int>(0, 2, 3);
val positives = list.filter { x -> x > 0 }
val positives02 = list.filter { it > 0 }
fun main() {
for (item in positives) {
print(item)
}
println()
for (item in positives02) {
print(item)
}
println()
val emailsList = listOf<String>("john@example.com", "john@example.com");
//检察元素是否存在于集合中
if ("john@example.com" in emailsList) {
println("存在")
}
//字符串内插
val name = "name"
println("Name $name")
//类型判断
val tempList = listOf<Any>(0, "2", 3.1);
for (obj in tempList) {
when (obj) {
is Int -> {
println("$obj is Int")
}
is String -> {
println("$obj is String")
}
else -> {
println("$obj is Any")
}
}
}
//只读list
val list = listOf<String>("a", "b", "c")
//访问map条目
val map = mutableMapOf("a" to 1, "b" to 2, "c" to 3)
println(map["a"])
map["a"] = 2
println(map["a"])
//遍历map或者pair型list
for ((k, v) in map) {
println("$k -> $v")
}
///区间迭代
for (i in 1..10) {
print(i)
}
println()
for (x in 2..10 step 2) {
print(x)
}
println()
for (x in 10 downTo 1) {
print(x)
}
println()
(1..10).forEach { a ->
print(a)
}
//延迟属性
// val p: String by lazy {}
//扩展函数
fun String.spaceToCamelCase() {}
"Convert this to camelcase".spaceToCamelCase()
//实例化一个抽象类
val myObject = object : MyAbstractClass() {
override fun doSomething() {
print("do something")
}
override fun sleep() {
print("sleep")
}
}
myObject.doSomething()
//if-not-null缩写
val files = File("Test").listFiles()
println(files?.size)
//if_not-null-else缩写
val files02 = File("Test").listFiles()
println(files?.size ?: "empty")
val fileSize = files?.size ?: run { }
println(fileSize)
//if null 执行一个语句
val values = mutableMapOf("email" to 1)
val email = values["email"] ?: throw IllegalStateException("Email is missing!")
//在可能会空的集合中取第一元素
val emails = listOf<Int>()
val mainEmail = emails.firstOrNull() ?: ""
//if not null 执行代码
var value: Int? = 1;
// var value: Int? = null;
value?.let {}
//映射可空值
val mapped = value?.let {
value = transformValue(it)
println(value)
} ?: 1
println(mapped)
println(transform("Red"))
println(test())
//if表达式
val x = 1;
val y = if (x == 1) {
"one"
} else if (x == 2) {
"two"
} else {
"other"
}
println(arrayOfMinusOnes(3))
///对一个对象实例调用多个方法(with)
val myTurtle = Turtle()
with(myTurtle) {
penDown()
for (i in 1..4) {
forward(100.0)
turn(90.0)
}
penUp()
}
///配置对象的属性(apply)
val myRectangle = Rectangle().apply {
var length = 4
var breadth = 5
var color = 0xFAFAFA
}
///java 7 的try-with-resource
val stream = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Files.newInputStream(Paths.get("/some/file.txt"))
} else {
TODO("VERSION.SDK_INT < O")
}
stream.buffered().reader().use { reader ->
println(reader.readText())
}
///可空布尔值
val b: Boolean? = true
if (b == true) else {
}
///交换两个变量
var a1 = 1
var b1 = 2
a1 = b1.also { b1 = a1 }
fun calcTaxes(): BigDecimal = TODO("Waiting for feedback from accounting")
}
//单表达式函数
fun theAnswer() = 42
fun theAnswer002(): Int {
return 42
}
//单表达式函数
fun transform002(color: String): Int = when (color) {
"Red" -> 0
"Green" -> 1
"Blue" -> 2
else -> throw IllegalStateException("error")
}
//返回类型为Unit的方法的构建器风格用法
fun arrayOfMinusOnes(size: Int): IntArray {
return IntArray(size).apply { fill(-1) }
}
//try-catch
fun test() {
val result = try {
println("try something")
} catch (e: ArithmeticException) {
throw IllegalStateException(e)
}
}
//返回when表达式
fun transform(color: String): Int {
return when (color) {
"Red" -> 0
"Green" -> 1
"Blue" -> 2
else -> throw IllegalArgumentException("Invalid color param value")
}
}
fun transformValue(a: Int): Int {
return 0
}
//创建单例
object Resource {
val name = "Name"
}
//抽象类
abstract class MyAbstractClass {
abstract fun doSomething()
abstract fun sleep()
}
class Turtle {
fun penDown() {}
fun penUp() {}
fun turn(degrees: Double) {}
fun forward(pixels: Double) {}
}
//inline fun <reified T: Any> Gson.fromJson(json: JsonElement): T = this.fromJson(json, T::class.java)
基本类型
数字
package com.example.kotlinstudy.基本类型
val one = 1
val threeBillion = 30000000000
val oneLong = 1L
val oneByte: Byte = 1
val pi = 3.14
val oneDouble = 1.0
val e = 2.7111111111
val eFloat = 2.71545353454f
val oneMillin = 1_000_000
val creditCardNumber = 1234_5678_9012_3456L
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010
fun main() {
fun printDouble(d: Double) {
println(d)
}
val i = 1
val d = 1.0
val f = 1.0f
printDouble(d)
println(oneMillin)
///JVM
///由于 JVM 对 -128 到 127 的整数(Integer)应用了内存优化,因此,a 的所有可空引用实际上都是同一对象。但是没有对 b 应用内存优化,所以它们是不同对象
val a: Int = 10000
//val a: Int = 10000
val boxedA: Int? = a
val anotherBoxA: Int? = a
println(boxedA == anotherBoxA)
//println(boxedA === anotherBoxA)
//显示数字转换
val b: Byte = 1
val i1: Int = b.toInt()
//很多请款无需显示类型转换
val l = 1L + 3
//数字运算
println(1 + 2)
println(2_500_000_000L - 1L)
println(3.14 * 2.71)
println(10.0 / 3)
//整数除法
val x = 5 / 2
//println(x == 2.5) // ERROR: Operator '==' cannot be applied to 'Int' and 'Double'
println(x == 2)
val x1 = 5L / 2
println(x1 == 2L)
val x3 = 5 / 2.toDouble()
println(x3 == 2.5)
//位运算
val x4 = (1 shl 2) and 0x000FF000
//浮点数比较
println(Double.NaN == Double.NaN) // false
println(listOf(Double.NaN) == listOf(Double.NaN)) // true
println(0.0 == -0.0) // true
println(listOf(0.0) == listOf(-0.0)) // false
println(listOf(Double.NaN, Double.POSITIVE_INFINITY, 0.0, -0.0).sorted())
}
布尔
package com.example.kotlinstudy.基本类型
fun main() {
val myTure: Boolean = true
val myFalse: Boolean = false
val boolNull: Boolean? = null
println(myTure || myFalse)
println(myTure && myFalse)
println(!myTure)
}
字符串
package com.example.kotlinstudy.基本类型
val str = "abcd 123"
fun main() {
val str = "abcd"
for (c in str) {
println(c)
}
println(str.uppercase())
println(str)
val s = "abc" + 1
println(s + "def")
val s1 = "hello, world!\n"
val text = """
for(c in "foo")
print(c)
""".trimIndent()
println(text)
//trimIndent取消前导空格
val text1 = """
|Tell me and I forget
|Tech me and I remember
|Involve me and I learn
|(Benjamin Franklin)
""".trimIndent()
println(text1)
//以竖线|为边界前缀
val text2 = """
|Tell me and I forget
|Tech me and I remember
|Involve me and I learn
|(Benjamin Franklin)
""".trimMargin("|")
println(text2)
val i = 10
println("i = $i")
val s2 = "abc"
println("$s2.length is ${s2.length}")
//插入美元字符
val price = """
${'$'}_9.99
"""
println(price)
}
数组
package com.example.kotlinstudy.基本类型
fun main() {
val asc = Array(5) { i -> (i * i).toString() }
asc.forEach { println(it) }
val x: IntArray = intArrayOf(1, 2, 3)
x[0] = x[1] + x[2]
val arr001 = IntArray(5)
val arr002 = IntArray(5) { 42 }
var arr003 = IntArray(5) { it * 1 }
arr001.forEach { println(it) }
arr002.forEach { println(it) }
arr003.forEach { println(it) }
}
无符号
package com.example.kotlinstudy.基本类型
val b: UByte = 1u
val s: UShort = 1u
val l: ULong = 1u
val a1 = 42u
val a2 = 0xFFFF_FFFF_FFFFu
val a = 1UL
类型检测与类型转换
package com.example.kotlinstudy.基本类型
fun main() {
val obj = "";
if (obj is String) {
print("a String")
}
if (obj !is String) {
print("Not a String")
} else {
print(obj.length)
}
//不安全的转换操作符
val y = 1
val x: String? = y as? String?
}
//智能转换类型
fun demo(x: Any) {
if (x is String) {
print(x.length)
}
if (x !is String) return
print(x.length)
if (x !is String || x.length == 0) {
}
if (x is String && x.length > 0) {
print(x.length)
}
when (x) {
is Int -> print(x + 1)
is String -> print(x.length + 1)
is IntArray -> print(x.sum())
}
}
控制流程
For循环
package com.example.kotlinstudy.控制流程
fun main() {
val collection = listOf<Int>()
for (item in collection) print(item)
val ints = listOf<Int>()
for (item: Int in ints) {}
for (i in 1..3) {
println(i)
}
for (i in 6 downTo 0 step 2) {
println(i)
}
val array = arrayOf("a", "b", "c")
for(i in array.indices) {
println(array[i])
}
for ((index,value ) in array.withIndex()) {
println("the element at $index is $value")
}
}
if表达式
package com.example.kotlinstudy.控制流程
fun main() {
val a = 2
val b = 2
var max = a
if (a < b) max = b
if (a > b) {
max = a
} else {
max = b
}
max = if (a > b) a else b
val maxLimit = 1
val maxOrLimit = if (maxLimit > a) maxLimit else if (a > b) a else b
println("max is $max")
println("maxOrLimit is $maxOrLimit")
val max002 = if (a > b) {
print("Choose a")
a
} else {
print("Choose b")
b
}
println(maxOrLimit)
}
//分支是简单布尔值
fun test() {
val y = 1
val x = 1
fun Int.isOdd(): Boolean {
return this%2 != 0
}
fun Int.isEven(): Boolean {
return this%2 == 0
}
when {
x.isOdd() -> print("x is odd")
y.isEven() -> print("y is even")
else -> print("x+y is odd")
}
}
enum class Bit {
ZERO, ONE
}
val numericValue = when (Bit.ONE) {
Bit.ONE -> 1
Bit.ZERO -> 0
//else不需要,因为枚举类型都覆盖了
}
enum class Color {
RED, GREEN, BLUE
}
when表达式
package com.example.kotlinstudy.控制流程
fun main() {
//When表达式
val x = 1;
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
3, 4 -> print("1 or 2")
else -> print("x is neither 1 nor 2")
}
//检测一个值在或者不在一个区间或者集合中
val validNumbers = listOf(1, 2, 3)
when (x) {
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range")
else -> print("none of the above")
}
fun hasPrefix(x: Any) = when (x) {
is String -> x.startsWith("prefix")
else -> false
}
//fun Request.getBody() =
// when (val response = executeRequest()) {
// is Success -> response.body
// is HttpError -> throw HttpException(response.status)
// }
//
}
while循环
package com.example.kotlinstudy.控制流程
fun main() {
var x = 0;
while (x > 0) {
x--
}
do {
val y = retrieveData()
} while (y != null) // y 在此处可见
}
fun retrieveData(): Int {
return 1
}
异常
package com.example.kotlinstudy.控制流程
fun main() {
//Try是一个表达式
val c = 5
val b = 1
val a: Int? = try {
c + b
} catch (e: NumberFormatException) {
null
}
//Nothing类型
//val s = person.name ?: throw IllegalArgumentException("Name required")
//当你调用该函数时,编译器会知道在该调用后就不再继续执行了:
//val s = person.name ?: fail("Name required")
//print(s)
//如果用 null 来初始化一个要推断类型的值,而又没有其他信息可用于确定更具体的类型时,编译器会推断出 Nothing? 类型:
val x = null “x”具有类型 `Nothing?`
val l = listOf(null) // “l”具有类型 `List<Nothing?>
}
//throw
fun throwTest() {
throw Exception("Hi There!")
}
//try catch
fun tryTest() {
try {
} catch (e: NumberFormatException) {
} finally {
}
}
//受检异常
//Appendable append(CharSequence csq) throw IOException
//Nothing表示不会返回的函数
fun fail(message: String): Nothing {
throw IllegalArgumentException(message);
}
返回与跳转
package com.example.kotlinstudy.控制流程
fun main() {
// val s = person.name ?: return
loop@ for (i in 1..100) {
for (j in 1..100) {
if (j > 2) {
println(j)
//continue@loop
break@loop
}
}
}
foo()
println()
foo002()
println()
foo003()
println()
foo004()
println()
foo005()
}
fun foo() {
listOf<Int>(1, 2, 3, 4, 5).forEach {
if (it == 3) {
return
}
print(it)
}
}
fun foo002() {
listOf<Int>(1, 2, 3, 4, 5).forEach lit@{
if (it == 3) {
return@lit
}
print(it)
}
}
fun foo003() {
listOf<Int>(1, 2, 3).forEach {
if (it == 3) return@forEach
print(it)
}
}
fun foo004() {
listOf<Int>(1, 2, 3).forEach(fun(value: Int) {
if (value == 3) return
print(value)
})
}
//当要返一个回值的时候,解析器优先选用标签限定的返回:
fun foo005() {
run loop@{
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return@loop 1
print(it)
}
}
}
类与对象
构造函数
一个类可以有一个主构造函数或者多个次构造函数
class Person construct(name: String) {}
若没有带任何注解或者可见性修饰符,可以省constructor
class Person(name: String) {}
初始化代码放在init
class InitOrderDemo(name: String) {
val firstProperty = "First property"
val init {
println("First")
}
val secondProperty = "Second property"
init {
println("Second")
}
}
fun main() {
InitOrderDemo("hello")
}
类体内声明属性初始化
class Customer(name:String) {
val customerKey = name.uppercase()
}
声明属性从主构造初始化
class Person(val name: String = "", var isEmployed: Boolean = true)
次构造函数
class Person(val pets: MutableList<Pet> = mutableListOf())
class Pet {
constructor(owner: Person) {
owner.pets.add(this)
}
}
关键词this调用另一个构造函数
class Person(val name: String) {
val children: MutableList<Person> = mutableListOf()
constructor(name: String, parent: Person) : this(name) {
parent.children.add(this)
}
}
创建类的实例
val invoice = Invoice()
抽象类
abstract class Polygon {
abstract fun draw()
}
class Rectangle : Polygon() {
override fun draw() {}
}
抽象成员覆盖非抽象的开放成员
open class PolygonExample {
open fun draw() {
}
}
abstract class WildShape : PolygonExample() {
abstract override fun draw()
}
继承
隐式继承Any
open class Base(p: Int)
class BaseExtend(p: Int) : Base(p)
使用super调用基类的构造函数
class MyView : View {
constructor(ctx: Context) : super(ctx)
constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs)
}
覆盖方法
添加显示修饰符,使方法能够被覆盖
//覆盖方法
open class Shape {
open fun draw() {}
fun fill() {}
}
open class Circle() : Shape() {
override fun draw() {
}
//禁止再覆盖
// final override fun draw() {
//
// }
}
覆盖属性
//覆盖属性
open class Shape2 {
open val vertexCount: Int = 0
}
class Rectangle2 : Shape2() {
override val vertexCount = 4
}
var可以override覆盖 val属性
interface Shape3 {
val vertexCount: Int
}
class Rectangle3(override val vertexCount: Int = 4) : Shape3
class Polygon3 : Shape3 {
override var vertexCount: Int = 0
}
派生类初始化顺序
先是完成基类初始化,再是派生类
使用super调用超类的属性和方法
open class Rectangle4 {
open fun draw() {
println("Drawing a rectangle")
}
val borderColor: String get() = "black"
}
class FilledRectangle : Rectangle4() {
override fun draw() {
super.draw()
println("Filling the rectangle")
}
val fillColor: String get() = super.borderColor
}
内部类访问外部类的超类
open class Rectangle {
open fun draw() { println("Drawing a rectangle") }
val borderColor: String get() = "black"
}
class FilledRectangle: Rectangle() {
override fun draw() {
val filler = Filler()
filler.drawAndFill()
}
inner class Filler {
fun fill() { println("Filling") }
fun drawAndFill() {
super@FilledRectangle.draw() // Calls Rectangle's implementation of draw()
fill()
println("Drawn a filled rectangle with color ${super@FilledRectangle.borderColor}") // Uses Rectangle's implementation of borderColor's get()
}
}
}
fun main() {
val fr = FilledRectangle()
fr.draw()
}
覆盖规则
open class Rectangle {
open fun draw() { /* …… */ }
}
interface Polygon {
fun draw() { /* …… */ } // 接口成员默认就是“open”的
}
class Square() : Rectangle(), Polygon {
// 编译器要求覆盖 draw():
override fun draw() {
super<Rectangle>.draw() // 调用 Rectangle.draw()
super<Polygon>.draw() // 调用 Polygon.draw()
}
}
属性
val & var
val是只读,var是可变
使用属性
fun copyAddress(address: Address): Address {
val result = Address()
result.name = address.name;
return result
}
getter & setter
///getter
class RectangleObject(val width: Int, val height: Int) {
// val area: Int
// get() = this.width * this.height
val area
get() = this.width * this.height
var areaText: String = ""
var stringRepresentation: String
get() = this.toString();
set(value) {
this.areaText = value
}
var setterVisibility: String = "abc"
private set
// var setterWithAnnotation: Any? = null
// @Inject set // 用 Inject 注解此 setter
//幕后字段
var counter = 0
set(value) {
if (value >= 0)
field = value
}
val isEmpty: Boolean
get() = this.counter == 0
}
幕后字段
//幕后字段
var counter = 0
set(value) {
if (value >= 0)
field = value
}
val isEmpty: Boolean
get() = this.counter == 0
编译时常量
const val SUBSYSTEM_DEPRECATED: String = "This subsystem is deprecated"
@Deprecated(SUBSYSTEM_DEPRECATED)
fun foo() {}
延迟属性
class MyTest {
//延迟初始化属性与变量
lateinit var subject: TestSubject
@SetUp
fun setup() {
subject = TestSubject()
}
@Test
fun test() {
subject.method() // 直接解引用
}
}
//检查是否初始化
if (foo::bar.isInitialized) {
println(foo.bar)
}
接口
package com.example.kotlinstudy.类与对象
import android.icu.text.Transliterator.Position
interface MyInterface {
val prop: Int
val propertyWithImplementation: String
get() = "foo"
fun bar()
fun foo() {
print(prop)
}
}
class Child : MyInterface {
override val prop: Int
get() = 29
override fun bar() {
}
}
///接口继承
interface Named {
val name: String
}
interface PersonA : Named {
val firstName: String
val lastName: String
override val name: String
get() = "$firstName $lastName"
}
data class Employee(
override val firstName: String,
override val lastName: String,
val position: Position,
) : PersonA
///解决覆盖冲突
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()
}
}
SAM
package com.example.kotlinstudy.类与对象
fun interface KRunnable {
fun invoke()
}
//SAM转换
fun interface IntPredicate {
fun accept(int: Int): Boolean
}
val isEven = object : IntPredicate {
override fun accept(int: Int): Boolean {
return int % 2 == 0
}
}
val isEvenLambda = IntPredicate { it % 2 == 0 }
fun main() {
println("Is 7 even? - ${isEvenLambda.accept(7)}")
::Printer
println("Is 7 even? - ${isEven02(7)}")
}
interface Printer {
fun print()
}
fun Printer(block: () -> Unit): Printer = object : Printer {
override fun print() = block()
}
//函数式接口与类型别名比较
typealias IntPredicate02 = (i: Int) -> Boolean
val isEven02: IntPredicate02 = { it % 2 == 0 }
可见性修饰符
包
- public 随处可见。
- private 文件内可见。
- internal 相同模块内可见。
- protected 修饰符不适用于顶层声明。
类
- private 类内部可见
- protected 类内部可见和子类可见
- internal 类声明的本模块内的任何客户端
- public 类声明的任何客户端
构造函数
主构造函数需要加construct,默认为public
例子
package com.example.kotlinstudy.类与对象
//包
fun baz() {}
class Bar {}
public var bar: Int = 5
private set
internal val boX = 6
///类成员
open class Outer {
private val a = 1
protected open val b = 3
internal open val c = 3
val d = 4
protected class Nested {
public val e: Int = 5
}
}
class SubClass : Outer() {
override val b: Int
get() = 5
override val c: Int
get() = 7
}
class Unrelated constructor(outer: Outer) {
}
//构造函数
class TestC private constructor(a: Int) {
}
扩展
package com.example.kotlinstudy.类与对象
//扩展函数
fun <T> MutableList<T>.swap(index1: Int, index2: Int) {
val tmp = this[index1]
this[index1] = this[index2]
this[index2] = tmp;
}
fun main() {
val list = mutableListOf(1, 2, 3)
list.swap(0, 2)
///扩展是静态解析的
open class Shape
class Rectangle : Shape()
fun Shape.getName() = "Shape"
fun Rectangle.getName() = "Rectangle"
fun printClassName(s: Shape) {
println(s.getName())
}
printClassName(Rectangle())
///扩展函数与组内函数名一致时取组内函数
class Example {
fun printA() {
println("A")
}
}
fun Example.printA() {
println("a")
}
Example().printA()
///重载函数不同签名成员函数
class Example1 {
fun printB() {
println("B")
}
}
fun Example1.printB(i: Int) {
println("$i")
}
Example1().printB(1);
///可空接受者
fun Any?.toString(): String {
if (this == null) return "null"
return toString()
}
//伴生对象的扩展
MyClass.printCompanion()
///扩展的作用域
val listA = listOf<String>("red", "green", "blue")
listA.getLongestString()
///扩展声明为成员
Connection(Host("kotl.in"), 443).connect()
BaseCaller().call(Base3()) // “Base extension function in BaseCaller”
DerivedCaller().call(Base3()) // “Base extension function in DerivedCaller”——分发接收者虚拟解析
DerivedCaller().call(Derived3()) // “Base extension function in DerivedCaller”——扩展接收者静态解析
}
//扩展属性
val <T> List<T>.lastIndex: Int
get() = size - 1
//伴生对象的扩展
class MyClass {
companion object
}
fun MyClass.Companion.printCompanion() {
println("companion")
}
///扩展声明为成员
class Host(val hostname: String) {
fun printHostname() {
print(hostname)
}
}
class Connection(val host: Host, val port: Int) {
fun printPort() {
print(port)
}
fun Host.printConnectionString() {
printHostname()
print(":")
printPort()
}
fun connect() {
host.printConnectionString()
}
fun Host.getConnectionString() {
toString() //调用Host.toString()
this@Connection.toString() //调用Connection.toString()
}
}
///
open class Base3 {
}
class Derived3 : Base3() {
}
open class BaseCaller {
open fun Base3.printFunctionInfo() {
println("Base extension function in BaseCaller")
}
open fun Derived3.printFunctionInfo() {
println("Derived extension function in BaseCaller")
}
fun call(b: Base3) {
b.printFunctionInfo()
}
}
class DerivedCaller : BaseCaller() {
override fun Base3.printFunctionInfo() {
println("Base extension function in DerivedCaller")
}
override fun Derived3.printFunctionInfo() {
println("Derived extension function in DerivedCaller")
}
}