比大小赋值:
方法一
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'} // 单引号表示字符
- 每次调filter都等于创建了一个新的list,即eager是一个list
- 如果想要使用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
- lambda传值
val dirty = 20
val waterFilter = { dirty: Int -> dirty/2 }
waterFilter(dirty)
- Syntax for function types
// 这里的意思是 传入一个int值然后返回一个int值, 然后在lambda中就不需要再声明传入值类型了。
val waterFilter: (Int) -> int = { dirty -> dirty / 2 }
- 高阶函数
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)
}