学习kotlin第九天_数据类、枚举类、密封类、嵌套类

来源:互联网 发布:淘宝微淘粉丝怎么增加 编辑:程序博客网 时间:2024/05/01 05:16

继续跟着官方文档踩坑......

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、标准库提供了PairTriple分别为两个和三个参数的标准数据类。

funmain(args: Array<String>) {
    valpair = Pair("zxy",23)
    valtriple = Triple("zxy",  "男","22")
    println(pair.toString())
    println(triple.toString())
}

4、密封类这里提到了枚举类,那我先跳过去学一下枚举类再回头学密封类吧......java类似,枚举类使用enum定义,每个枚举常量都是一个对象,用逗号隔开。可以直接使用小括号初始化。可声明一个抽象方法,然后在枚举常量后声明匿名类valuesOf()方法如果指定的名称与定义的枚举常量名不匹配,则报异常IllegalArgumentExceptionname属性表示其名称,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
    is
Sum ->eval(expr.e1) + eval(expr.e2)
    NotANumber -> Double.NaN
}

7kotlin中的类也能有类型参数。一般情况下初始化时需要提供类型参数。如果可以推断出来数据类省略类型参数。

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!明天周末,打篮球去了

原创粉丝点击