继续跟着官方文档踩坑......
坑1、数据类是只保存数据的类,用data标记。
data class User(val name: String, val age: Int)
编译器自动对应主构造函数中的属性导出以下成员
l equals()/hashCode()对;(没懂.....)
l toString()的格式是User(name=zxy, age=23);(在java中如果没有重写toSting()方法则打印的是地址,如com.tshouyi.hello.Bean@7ea987ac)
l Kotlin支持解构声明。
fun main(args: Array
val u: User = User("zxy", 23)
val (name, age) = u
println(name)
println(age)
}
l copy()函数支持我们复制一个对象并改变其中一部分属性。
fun main(args: Array
val jack = User("Jack", 1)
val olderJack = jack.copy(age = 3)
println(jack.toString())
println(olderJack.toString())
}
坑2、当主构造函数的参数都有默认值时,自动生成一个无参构造函数。否则调用无参构造函数时报No value passed for parameter xxx
data class User(val name: String = "", val age: Int = 0)
fun main(args: Array
val u: User = User()
}
坑3、标准库提供了Pair和Triple分别为两个和三个参数的标准数据类。
fun main(args: Array
val pair = Pair("zxy", 23)
val triple = Triple("zxy", "男","22")
println(pair.toString())
println(triple.toString())
}
坑4、密封类这里提到了枚举类,那我先跳过去学一下枚举类再回头学密封类吧......和java类似,枚举类使用enum定义,每个枚举常量都是一个对象,用逗号隔开。可以直接使用小括号初始化。可声明一个抽象方法,然后在枚举常量后声明匿名类。valuesOf()方法如果指定的名称与定义的枚举常量名不匹配,则报异常IllegalArgumentException,name属性表示其名称,values()方法用于生成这些常量构成的数组,ordinal属性表示对应的声明顺序。枚举定义和其它成员变量间用分号隔开。
enum class Color(val rgb: Int) {
RED(0xFF0000){
override fun color()=GREEN
},
GREEN(0x00FF00){
override fun color()=RED
},
BLUE(0x0000FF){
override fun color()=BLUE
};
abstract fun color():Color
}
fun main(args: Array
println(Color.valueOf("BLUE"))
for ( c in Color.values()){
println(c.name+"\tordinal:"+c.ordinal+"\toverride color is "+c.color())
}
}
坑5、可以使用 enumValues
enum class RGB { RED, GREEN, BLUE }
inline fun <reified T : Enum<T>> printAllValues() {
print(enumValues<T>().joinToString { it.name })
}
fun main(args: Array
printAllValues
}
尴尬了,泛型和reified关键字都不太理解是个啥...+-
坑6、 当一个值为有限集中的类型,而不能有其它类型时,可以用密封类来表示受限的类继承结构。与枚举不同的是密封类的一个子类可以包含状态的多个实例。密封类用sealed声明,密封类的子类必须和它在同一个文件中。在使用when的时候,如果已经覆盖了所有情况,则不再需要else语句。(其实我也不大懂这密封类。。。)
sealed class Expr
data 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
}
坑7、kotlin中的类也能有类型参数。一般情况下初始化时需要提供类型参数。如果可以推断出来数据类省略类型参数。
class Box<T>(t: T) {
var value = t
val box : Box
val box2 = Box(1)
}
唉,这泛型真心看不懂呀,java中的泛型就没好好学。先不耽搁时间了,等回头再补补泛型。
坑8、类可以嵌套在其它类中。调用时通过“外部类.嵌套类.方法”调用嵌套类中的方法。
class Outer {
private val bar: Int = 1
class Nested {
fun foo() = 2
}
}
val demo = Outer.Nested().foo() // == 2
内部类用inner标记,可以访问外部成员
class Outer {
private val bar: Int = 1
inner class Inner {
fun foo() = bar
}
}
val demo = Outer().Inner().foo() // == 1
可以用对象表达式创建匿名内部类,对于函数式java接口,可以使用带接口类型前缀的lambda表达式创建它
fun main(args: Array
val r = object : Runnable {
override fun run() {
println("main?")
}
}
val s = Runnable { println("s") }
r.run()
s.run()
}
明天见,额,no!明天周末,打篮球去了