一、类组成
1.主构造函数
参数类型写法的三种情况:
//_name 带下划线的是临时类型,必须要二次转化才可以用
class A(_name: String) {
val mName = _name;//1.直接给类成员变量赋值
var mName2:String=""
init{
mName2= _name//2.在初始化代码块中使用或者赋值
}
fun log() {
System.out.println(mName)
}
}
//就可以直接用(相对比上面的写法是简洁语法)
//与普通属性一样,主构造函数中声明的属性可以是可变的(var)或只读的(val)
class B(val name: String) {
fun log() {
System.out.println(name)
}
}
//如果构造函数有注解或可见性修饰符,这个 constructor 关键字是必需的
//没有的话可以省略,比如上面两种写法
class C private constructor(val name: String) {
fun log() {
System.out.println(name)
}
}
2.次构造函数
次构造函数需要委托给主构造函数(直接委托或者通过别的次构造函数间接委托)
class B(val name: String) {
constructor(sex:String,name:String):this(name)
fun log() {
System.out.println(name)
}
}
!!再者次构造函数不能用var或者val修饰
3.初始化块
执行顺序:主构造函数→ 初始化代码块→ 次构造函数
但是,成员变量和初始化代码块的顺序是按书写的顺序执行的,谁在上面谁就先执行
val name="tina" //第一步
init{
//第二步
}
val sex="女" //第三步
4.延迟加载
- lateinit
class AA {
lateinit var name: String//可以先不赋值,什么时候用到什么时候赋值
fun log() {
if (::name.isInitialized) {
System.out.println("初始化")
} else {
System.out.println("还没有初始化")
}
}
}
- by lazy
val date by lazy {
println("")
}
不能用var修饰,因为只可读
Type 'Lazy' has no method 'setValue(AA, KProperty<*>, Unit)'
and thus it cannot serve as a delegate for var (read-write property)
5.field 隐藏域变量
变量的set get方法中,赋值用
二、类的种类
匿名类
object的使用
open class Father {
open fun add(info: String) = println(info)
open fun del(info: String) = println(info)
}
class Son : Father() {
override fun add(info: String) {
super.add(info)
}
override fun del(info: String) {
super.del(info)
}
}
fun main() {
//匿名对象表达式方式
val son: Father = object : Father() {
override fun add(info: String) {
super.add(info)
}
override fun del(info: String) {
super.del(info)
}
}
//具名方式
val son2 = Son()
}
数据类
关键词:data
特点:已经写好了一些需要使用的常用方法
解构
data class Food(val name: String, val number: Int)
fun main() {
val (name, number) = Food("牛奶", 2)
println("name=$name number=$number")
}
内部类(嵌套类)
嵌套类 默认是嵌套类,里面的类不能访问外部的类
内部类 里面的类添加inter 关键字,然后就可以访问外部类的信息
枚举类
//第一种普通方法
enum class Week{
星期一,
星期二,
星期三
}
fun main(){
println(Week.星期一)
}
//第二种 定义函数方式
class LimbsInfo(var name: String, var length: Int) {
fun show() {
println("$name 的长度是:$length")
}
}
enum class Limbs(private val limbsInfo: LimbsInfo) {
//定义函数
LEFT_HAND(LimbsInfo("左手", 22)),
RIGHT_HAND(LimbsInfo("右手", 22));
fun show() = "左右手:${limbsInfo.name}的长度是${limbsInfo.length}"
fun update(limbsInfo: LimbsInfo) {
this.limbsInfo.name = limbsInfo.name
this.limbsInfo.length = limbsInfo.length
println(show())
}
}
fun main(){
println(Limbs.LEFT_HAND.show())//输出内容
Limbs.LEFT_HAND.update(LimbsInfo("右腿", 100))//更新内容
}
结果:
左右手:左手的长度是22
左右手:右腿的长度是100
密封类
感觉跟枚举很像
sealed class Exams {
object Type1 : Exams()
object Type2 : Exams()
object Type3 : Exams()
class Type4(val name: String) : Exams()
}
class Teacher(private val exams: Exams) {
fun show() =
when (exams) {//必须全包含集中类型type1-->type4
is Exams.Type1 -> "type1"
is Exams.Type2 -> "type2"
is Exams.Type3 -> "type3"
is Exams.Type4 -> "type4${exams.name}"
}
}
fun main() {
println(Teacher(Exams.Type1).show())
println(Teacher(Exams.Type4("李四")).show())
println(Exams.Type1 === Exams.Type1)//true
println(Exams.Type4("张三") === Exams.Type4("张三"))//false
}
其他
运算符重载
//重载+运算符
data class AddClass(var number1: Int, var number2: Int) {
operator fun plus(p1: AddClass): Int {
return (number1 + p1.number2) + (number2 + p1.number2)
}
}
fun main() {
println(AddClass(1, 1) + AddClass(2, 2))
}
伴生对象
相当于java中的static
companion object {
const val info = "2323"
}
三、类型转化
as 强转
is 判单类型
四、继承
类要被open修饰才可以继承