Kotlin学习 – Class篇(与JAVA对比)

  • Post author:
  • Post category:java




下列代码块中,上面是kotlin代码,下面是与之比较的java代码


  • 声明类

    koltin:

    class

    关键字定义类,默认不可继承,当主构造函数没有任何注解或可见性修饰符时,可省略

    constructor

    关键字

    java:等同于 final class
class Invoice constructor() {}
final class Invoice {}
  • 构造函数

    kotlin:有一个主构造函数以及零个或多个次构造函数,主构造函数不能包含任何代码,初始化代码放到

    init

    关键字作为前缀的代码块中

    java:可以定义多个构造函数,不分主次
class Person constructor(firstName: String) {
    init {
        print("我是init代码块,等同于主构造函数代码块")
    }
    constructor(firstName: String, lastName: String) : this(firstName) {
        print("我是次要构造函数,我可以有自己的代码块")
    }
}
public class Person {
    public Person(String firstName) {
        System.out.println("java代码不分主次,都可以拥有自己的构造函数代码块");
    }
    public Person(String firstName, String lastName) {
        System.out.println("java代码不分主次,都可以拥有自己的构造函数代码块");
    }

}
  • kotlin可以拥有多个

    init

    代码块,与属性初始化器交织在一起,按照他们出现在类中的顺序执行,主构造函数的参数可以在初始化代码块中使用
class Person constructor(firstName: String) {
	val firstProperty = "我是第一个属性,我的执行顺序是1".also(::print)
    init {
        print("我是第1个init代码块,我的执行顺序是2")
        print(firstName) // 可以在代码块中使用主构造函数的参数
    }
    val firstProperty = "我是第二个属性,我的执行顺序是3".also(::print)
    init {
		print("我是第2个init代码块,我的执行顺序是4")
	}
    constructor(firstName: String, lastName: String) : this(firstName) {
        print("我是次要构造函数,我可以有自己的代码块")
    }
}
  • koltin构造函数的使用,与java相比的简洁写法
// 正确的写法
class Person constructor(val firstName: String, val lastName: String) {
    fun printName() {
        print("我的名字是:$firstName $lastName")
    }
}
// 错误的写法
class Person constructor(firstName: String, lastName: String) {
    fun printName() {
    	// err,这里无法使用firstName与lastName
        print("我的名字是:$firstName $lastName")
    }
}
public class Person {
    private String firstName;
    private String lastName;
    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    public void printName() {
        System.out.println("我的名字是:" + firstName + lastName);
    }
}
  • 次要构造函数,这种写法不能存在主构造函数
class Person {
    constructor(fistName: String) {
        println("次要构造函数")
    }
    constructor(fistName: String, lastName: String) {
        println("次要构造函数")
    }
}
  • 如果存在主构造函数,则次要构造函数必须委托给主构造函数,或者委托给其他次要构造函数间接委托,委托到同一类的另一个构造函数,使用

    this

    关键字
class Person constructor(fistName: String) {
    constructor(fistName: String, lastName: String) : this(fistName) {
        println("次要构造函数1,通过this委托给主构造函数")
    }
    constructor(fistName: String, lastName: String, age: Int) : this(fistName, lastName) {
        println("次要构造函数2,通过this间接委托给主构造函数")
    }
}
  • 如果非抽象类没有声明任何(主或次)构造函数,则会自动生成一个不带参数的主构造函数,可见性是

    public

    ,如果你不希望类有一个公有构造函数,则可以
class Person private constructor() {} 
  • kotlin 没有 new 关键字
val person = Person()
Person person = new Person();
  • kotlin 所有类的超类 Any
class Person : Any() {}
class Person extends Object {}

  • open

    关键字,使类可以被继承,kotlin 类默认不能被继承
// 基类
open class Base {}
// 派生类
class Person : Base() {}
  • 如果派生类没有没有主构造函数,则每个次构造函数必须使用

    super

    初始化基类
// 基类
open class Base(firstName: String) {
    constructor(firstName: String, lastName: String) {}
}
// 派生类没有主构造函数,使用 super 初始化基类
class Person : Base {
    constructor(firstName: String) : super(firstName) {}
    constructor(firstName: String, lastName: String) : super(firstName, lastName) {}
}
  • 派生类想重写父类的方法,父类方法必须使用

    open

    关键字修饰,子类方法必须使用

    override

    修饰,

    override

    默认是开放的,如果想禁止覆写,使用final关键字

    ps:open 修饰方法所在类,如果没有使用open修饰类,不会起作用,
// 基类
open class Base {
    open fun hello() {
        println("base")
    }
    fun hello2() {
        println("base")
    }
}
// 派生类
class Person : Base() {
	// hello方法可以被重写
    override fun hello() {}
    // hello2方法不可以被重写,因为没有使用 open 修饰
}
  • 属性覆盖与方法覆盖类似

    var

    可以覆盖

    val

    ,反之,则不行



版权声明:本文为u012421093原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。