kotlin小记(1)
1.次构造函数
可以理解为是在对主构造函数进行”重载“,但是必须要直接或间接代理上主构造函数,使得主构造函数的值传入次构造中;
open class Person(var a1 : Int) { constructor(a2 : String) : this(0) { } constructor(a1 : Int, a2 : Int) : this(a1){ }
}
2.open关键字
只有被open修饰的类,才可以被继承。被open修饰的方法,才能被重写.被open修饰的属性,才能够被重写(属性被open修饰后,必须初始化,不能被lateinit修饰,也不能只在init中被初始化)
open class Person(var a1 : Int) { open fun test(){}open var time : Int
}
3.类的修饰符
- classModifier: 类属性修饰符,标示类本身特性。final // 类不可继承,默认属性open // 类可继承,类默认是final的abstract // 抽象类 enum // 枚举类annotation // 注解类- accessModifier: 访问权限修饰符private // 仅在同一个文件中可见protected // 同一个文件中或子类可见public // 所有调用的地方都可见internal // 同一个模块中可见
4.子类继承
子类有主构造函数, 则基类必须在主构造函数中立即初始化。
子类没有主构造函数,则基类可以在类头或次构造函数中初始化
open class Person(var a1 : Int) { }
//子类有主构造函数
class child(a1 :Int) : Person(100){ } //子类没有主构造函数
class man : Person(100) { } class felman : Person{ constructor(a1 : Int) : super(101){ }
}
5.属性重写
你可以用一个var属性重写一个val属性,但是反过来不行。因为val属性本身定义了getter方法,重写为var属性会在衍生类中额外声明一个setter方法(子类重写父类属性,也就相当于必须重写该属性的 getter 和 setter 方法,而子类中的 val 不能有 setter 方法,所以无法“覆盖”父类中 var 的 setter 方法,相当于缩小了父类中相应属性的使用范围,是不允许的,就像我们不能把父类中一个 public 方法重写成 private 方法一样。)
6.拓展函数
对类的属性和方法进行拓展,不需要继承和装饰器模式
一种静态行为,对被扩展的类代码本身不造成任何影响
class Test { var num = 1
} fun Test.goo(){ println("${num}")
}fun <T> MutableList<T>.len() : Int { return this.size
}
拓展函数是静态解析的
open class Cclass D: C()fun C.foo() = "c" // 扩展函数 foofun D.foo() = "d" // 扩展函数 foofun printFoo(c: C) {println(c.foo()) // 输出 c
}
若扩展函数和成员函数一致,则使用该函数时,会优先使用成员函数。
7.泛型
泛型:将类型作为一个参数使用,可以用在类,接口,方法上
使用 out 使得一个类型参数协变,协变类型参数只能用作输出,可以作为返回值类型但是无法作为入参的类型:
in 使得一个类型参数逆变,逆变类型参数只能用作输入,可以作为入参的类型但是无法作为返回值的类型:
class test2<out T>(val time : T){ fun getTime() : T{ return time }
} class test3<in T>(){ fun getTime(time : T){ }
}
8.数据类在结构声明中使用
data class User( var name : String, var age : Int
) fun main() { val jane = User("jane", 35) val(name, age) = jane println("$name, $age is ")
}
9.密封类
和枚举的对比
enum class Color(var lab : Int, var namex : String){ RED(0xFF0000, "red"), //每个实例携带的信息相同GREEN(0x00FF00, "green"), BLUE(0x0000FF, "blue")
}sealed class Users{ object Unknown : Users() data class Man(val age: Int) : Users() //实例可携带不同的信息data class Felman(val name: String) : Users()
}
每个枚举常量只存在一个实例,而密封类的一个子类可以有可包含状态的多个实例。
密封类通常和when搭配使用
sealed class Users{ object Unknown : Users() data class Man(val age: Int) : Users() data class Felman(val name: String) : Users()
} fun getSex(users: Users) : Int = when(users){ Users.Unknown -> 0 //没有额外参数时,不用isis Users.Man -> 1 is Users.Felman -> 2 //因为涵盖了所有实例分支,所以不用else
}
10,枚举类实现单例,每个枚举常量只存在一个实例
枚举类已经隐式地继承了Enum类,所以枚举类不能继承其他类,但是可以实现接口
enum class Singleton{ INSTANCE;
}// 编译器生成的Java代码(简化版)public final class Singleton extends Enum<Singleton> {public static final Singleton INSTANCE = new Singleton();private Singleton() {// 私有构造函数}// 其他枚举相关方法...
}