下列代码块中,上面是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 版权协议,转载请附上原文出处链接和本声明。