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