1. 面向对象

1.1 创建一个类 + 构造方法说明

class TestCons constructor() {
}

  kotlin采用 constructor 关键字来代表构造方法,其中的 constructor 可以省略,但是如果加上权限修饰符就不能省略了:

class TestCons constructor() {
}

// 有参构造
class TestCons constructor(age:Int, name:String) {
}

// 如果加上权限 private 修饰符,就不能省略 关键字 constructor了
class TestCons private constructor(age:Int, name:String) {
}

    如果是 无参构造函数,可以省略 constructor()。那么如果想在构造方法中做一些参数初始化,该如何进行呢,就需要用到 init 代码块了。

    init 代码块 的执行顺序在构造方法之后,如下所示:

class TestCons {
    var name:String = ""
    var age:Int = 0
    init {
        name = "zhangsan"
        age = 10
    }
}

1.2 带参构造函数 及 初始化

class TestCons(name: String, age: Int) {

    var name: String = ""
    var age: Int = 0

    init {
        this.name = name
        this.age = age
    }

    fun print() {
        println("TestCons name = $name, age=$age")
    }
}

// 测试类
var test = TestCons("zhangsan", 20)
test.print()

// 输出
TestCons name = zhangsan, age=20

    这种带参构造函数,然后还需要在 init 代码块中初始化的方式是不是很麻烦,kotlin提供了另外一种简单的方式

class TestCons(val name: String, val age: Int) {

    fun print() {
        println("TestCons name = $name, age=$age")
    }
}

// 测试类
var test = TestCons("zhangsan", 20)
test.print()

// 输出
TestCons name = zhangsan, age=20

    在构造方法中,将两个参数前面添加 val 或者 var 关键字,将其作为本类中的变量,输出结果一样。

1.3 主构造函数 和 次构造函数

java模式:

package compare.java;

public class Rect2 {

    private int length;
    private int width;

    public Rect2() {
    }

    public Rect2(int length, int width) {
        this.length = length;
        this.width = width;
    }

    public void smile() {
        System.out.println("java length = " + length);
    }
}

kotlin模式:

package compare.kt

class Rect2() { // 主构造函数
    private var length = 0
    private var width = 0

    constructor(length: Int, width: Int) : this() { // this就是主构造函数
        this.length = length
        this.width = width
    }

    fun smile() {
        println("rect2 smaile length = $length")
    }
}

测试类:

package compare

fun main(args: Array<String>) {
    var rect1 = compare.kt.Rect2(20, 20)

    var rect2 = compare.kt.Rect2()

    var rec3 = compare.java.Rect2()

    var rec4 = compare.java.Rect2(20, 20)
}

    在java中并没有主次构造方法的区别,但是Kotlin中有主次构造方法

        1. 跟随在class 之后的就是主构造方法

        2. 主构造方法只能有一个,次构造方法可以有多个

        3. 如果从次构造函数进来,之后还要再走一次主构造函数

2. 抽象类 和 多态

2.1 抽象类

/**
	 * 创建抽象类
	 */
	abstract class Human(name: String) {
	    abstract fun eat()
	}

	// 实现抽象类
	class Man(name: String) : Human(name) {
	    override fun eat() {
	        println("man eat")
	    }
	}

2.2 继承 + 重写 + 父类引用指向子类对象

open 关键字:

        1. 父类在class前使用,才可以使其子类能继承

        2. 子类重写父类的方法,父类方法前需要添加才能重写

// 子类
	class Son : Father() {
	    override fun action() {
	        println("father do action")
	    }
	}

	// 父类
	open class Father() {
	    var character = "性格内向"
	    open fun action() {
	        println("father do action")
	    }
	}
	
	// 测试类
	fun main(args: Array<String>) {
	    var father: Father = Son()

	    father.action()
	}

3. 接口

3.1 接口

interface IMan {
	    fun eat()
	}

	class Man2:IMan {
	    override fun eat() {
	        println("eat food")
	    }
	}

3.2 接口和抽象类区别

        在使用的时候,抽象类需要:带个括号,而接口直接写就可。

class Man3(name: String) : Human(name), IMan {
	override fun eat() {
	}

	override fun eat2() {
	}
}

/**
 * 创建抽象类
 */
abstract class Human(name: String) {
    abstract fun eat()
}

interface IMan {
	fun eat2()
}

4. 委托 ,代理和单例

        by 关键字:将洗碗的操作 委托给BigHeadSon,调用 SmallHeadFather.washing时会执行到BigHeadSon的washing方法

class SmallHeadFather : IWashBall by BigHeadSon() {

	}

	class BigHeadSon : IWashBall {
    override fun washing() {
        	println("BigHeadSon washing")
    	}
	}

	interface IWashBall {
    	fun washing()
	}

// 测试方法
fun main(args: Array<String>) {
    var smallHeadFather = SmallHeadFather()
    smallHeadFather.washing()
}

4.1 变形一

    在委托前后还可以做一些其他的事情。

class SmallHeadFather : IWashBall by BigHeadSon() {

	    override fun washing() {
	        println("委托前可以做一些事情")
	        BigHeadSon().washing()
	        println("委托后也可以做一些事情")
	    }
	}

 如果这样的话 by 关键之之后的 BigHeadSon(),以及 调用washing方法的 BigHeadSon(),会分别创建一个对象,这样会造成对象的 内存空间的浪费。

4.2 变形二

    object 关键字:被修饰的类已经在jvm内存中创建了一个实例,有且只有一个,就是单例类。

    使用的时候就可以不用带括号,直接类名即可。

object BigHeadSon : IWashBall { 
	    override fun washing() {
	        println("BigHeadSon washing")
	    }
	}

	class SmallHeadFather : IWashBall by BigHeadSon {

	    override fun washing() {
	        println("委托前可以做一些事情")
	        BigHeadSon.washing()
	        println("委托后也可以做一些事情")
	    }
	}

5. 静态类 和 静态方法

5.1 静态类

    使用 object 关键字修饰的即为静态类。

object StaticUtil{
	    fun method()
	    ...

5.2 普通类中的静态方法

    companion object 关键字:大括号里面的都是静态的。

class StaticUtils {
	    companion object { // 包裹范围内 属于静态方法,静态属性

	    	val TAG = "lbs" // 定义常量

	        fun method()
	        ...
	    }
	}