kotlin

311 阅读2分钟

比大小赋值:

方法一

val x = 10
val y = 20
val max = if(x>y) x else y //巨简化
val min = if(x<y) y else x

方法二: 当遇到if..else后面是需要跟代码块当时候,

if和else后面当代码块会以最后一条语句作为返回值

val x = 10
val y = 20
val max = if(x>y){
	println("x > y ")
	x	
} else {
	println("x<=y")
	y
}

String & List

' ' 单引号use for character

" " 双引号use for string, 他们之间不可相互转换

filter

val decorations = listOf ("rock","pagoda","plastic plant","alligator","flowerpot")
val eager = decorations.filter {it[0] == 'p'} // 单引号表示字符
  1. 每次调filter都等于创建了一个新的list,即eager是一个list
  2. 如果想要使用kotlin的lazy behavior, 可以用sequences

一、Sequence

sequence is a collection that can only look at one item at a time start from beginning to the end.

val filtered = decorations.asSequence().filter { it[0] == 'p'} // 此时filtered是一个sequence.
val filteredToList = filtered.toList() //这个时候sequence被转化成了list

val lazyMap = decorations.asSequence().map {
	println("map: $it")    // 此处map是不能成功打印decorations中所有内容的,只能打印第一个
}

println ("first: ${lazyMap.toList()}")  // 这时会打印第一个值
println ("first: ${lazyMap.toList()}")  // 这时会打印整个list

二、filter 的几个用法

// 1. Sorting curries by string length
spices.filter{it.contains("curry")}.sortedBy {it.length}
 
// 2. Filtering by those that start with 'C' and end with 'e'
	// 方法一: filter里面包另外一个filter
spices.filter {
	it.startsWith('C').filter { it.endsWith('e') }
}

	//方法二:filter里面包一个判断语句
spices.filter{
	{ it.startWith('C') && it.endsWith('e') }	
}

// 3. Filtering the first 3 items by 'c'
spices.take(3).filter { it.startWith('C')}

Lambda

a expression that makes a function, we declare a function with no name

val swim = {println("swim\n")}  //这是一个最简单的 lambda function
  1. lambda传值
val dirty = 20
val waterFilter = { dirty: Int -> dirty/2 }
waterFilter(dirty)
  1. Syntax for function types
// 这里的意思是 传入一个int值然后返回一个int值, 然后在lambda中就不需要再声明传入值类型了。
val waterFilter: (Int) -> int = { dirty -> dirty / 2 }
  1. 高阶函数

any function that take function as the argument

val dirty = 20
val waterFilter: (Int) -> int = { dirty -> dirty / 2 }
fun updateDirty ( dirty:Int, operation:(Int)->Int ) : Int {
	return operation(dirty)
} 

fun feedFish(dirty : Int) = dirty + 10

fun dirtyPeocessor() {
	dirty = updateDirty(dirty, waterFilter) // waterFilter是一个lambda函数,可直接传入
	dirty = updateDirty(dirty, ::feedFish)  // feedFish不是一个lambda函数,所以用::导入function
}

Function

val width: Int = 20
val height: Int = 40
val length: Int = 100
fun myFunc() = width * height * length / 1000
//用上面这个方法可以很好的简化代码,体现kotlin的特点。不一定要写写成 {...}的形式

Class

class Aquarium {
	var width: Int = 20
	var height: Int = 40
	var lenght: Int = 100
	
	var volume : Int
		get() = return width * height * length / 1000
		set(value) {height = (value * 1000) / (width * length) }
}
  • 上面代码中的长宽高如果用var, 那么在调用的时候,就可以被修改,如果不想被修改就使用val。
  • volume可以写成方法,但是此处对于调用的人来说,其实只需要一个值,所以返回一个值而不是方法会更加合适 → 可以将volumn方法给改成一个property, 类型为Int, 然后换行写一个get 方法。 而get方法也可以被简化为一行,不需要使用 {} 。 setter实现也是一样 (但是要注意,如果加setter表明这个值是可以变的,所以要用var, 不能用val)
  • internal: can visible in anywhere in the same module. can use it from anywhere inside our project, but when you compile the library, it won't exported as a function
  • private: can only visible inside class, subclasses cannot see.
  • public: can visible everywhere. Class and public, default
  • protected - can visible inside class, subclasses can see

constructors

一. 只用默认的constructor

class className(var para1: int, val para2: int) {
}

在参数加上 var / val 后会自动带有构造函数,不需要再另外写了

二、另外写一个构造函数(secondary constructor)

如果确实需要添加一个constructor, 那么必须call primary constructor(即 Kotlin 自动生成的默认的constructor)

class className(var para1: int, val para2: int) {
	constructor() : this()
}

三、Init

可以写很多个init, 并且所有的init都会比secondary constructor先执行

class Fish() {
	init {
		// init 和 constructor差不多,可以把逻辑放入这里来初始化properties   
	}
}

Inheritance

open class classA (var length: Int = 100, var width: Int =20, var height: Int = 40) {
	...
}

classB(length: Int, width:Int, height:Int, var volume:Int) : classA(length, width, height) {
...
}
  • 如果想要被其他类继承,那么首先需要将这个类open
  • 如果父类(classA)已经神明过了的变量,就不能在重新声明,即下面classB的lenght和width会报错,因为加了 var( 除非classA中变量是private的)
classB(var length: Int, var width: Int): classA(length, width, height){}

Interface

interface VS abstract class

  • interface 不能有任何的constructor logic, abstract class是可以有的
  • interace不能保存状态
  • interface delegation
    • let u add features to a class via composition
  • composition
    • is when u use an instance of another class as opposed to inheriting from it.
  • instead of requiring the callers subclass, a giant abstract class, give a small interface and let them delegate(代表,委托,representative) those interfaces to an obj.

how to do composition?

fun delegate(){
	val pleco = plecostomus()
	println("fish has color ${pleco.color}")
	pleco.eat()
}

interface FishColor {
	fun eat()	//只是抽象的,并未被实现,要在class中重写实现
}
interface FishAction {
	val color: String  //只是抽象的,并未被实现,要在class中重写实现
}

class Plecostomus: FishAction, FishColor {
	override fun eat() {
		println("eat algae")
	}
	ovveride val color: String
	get() = "gold"
}

interface delegation

用interface delegation来提供color implementation

  • 我们需要一个obj that know 怎么提供颜色
class GoldColor: FishColor {
	override val color = "gold"
}
// 但是给goldcolor用这么多的instance是不合理的,且他们都做都是一样都事情,所以这里我们可以用object来替换class

  • object在kotlin中,是用来声明一个class但是它只能有一个instance
object GoldColor: FishColor {
	override val color = "gold"
}
class Plecostomus: FishAction, 
									 FishColor by GoldColor {
	override fun eat() {
		println("eat algae")
	}
}
  • 但是以上方法还不能修改fishcolor,只能是gold,那么要让gold变成默认颜色,实际颜色根据传入值而定,那么可以改成以下都方式:
object GoldColor: FishColor {
	override val color = "gold"
}
class Plecostomus(fishColor: FishColor = GoldColor): FishAction, 
									 FishColor by fishColor {
	override fun eat() {
		println("eat algae")
	}
}
object RedColor: FishColor {
	override val color = "red"
} // 如果传入都是红色,那么就会返回红
  • 多一个action例子
class PrintingFishAction(val food: String): FishAction {
	override fun eat() {
		println(food)
	}
}

class Plecostomus(fishColor: FishColor = GoldColor): 
								   FishAction by PrintingFishAction("a lot of algae")
									 FishColor by fishColor

用这样都方式以后,class都不需要再写实现了,花括号都不要了

Data class

3 special type classes

object class //only have one instance
enum class
sealed class
object class MobyDichWhale {
	val author = "Herman Melville"
	fun jump() {...}
}
enum class Color(val rgb: Int) {
	RED(0xFF0000),
	GREEN(0x00FF00),
	Blue(0x0000FF)
}