kotlin 类
kotlin 类
kotlin中使用class申明类
构造函数
构造函数分为主构造函数、次构造函数
主构造函数
kotlin中可以在申明类时申明一个构造函数,并且次构造函数为 主构造函数
1 | // 申明了主构造函数 |
如果主构造函数没有使用任何注解或者修饰符,则可以省略constructor关键字
1 | class Person (var name: String, var age: Int ) {} |
主构造函数不能含有代码块,有需要初始化的代码可以放在以init关键字作为前缀的初始化块中。
其中init可以申明多个,会根据代码顺序来执行。
1 | class Person (var name: String, var age: Int ) { |
如果没有申明主构造函数,系统会自动创建一个无参的主构造函数。
次构造函数
次构造函数必须要用constructor申明,
如果有主构造函数,必须将次构造函数委托给主构造函数
1 | class MyPerson(str: String, var age: Int) { |
初始化init代码块实际上会成为主构造函数的一部分。
当次级构造函数委托给主构造函数,init代码块会成为次级构造函数的第一句语句。
即使该类没有主构造函数,这种委托也会隐式发生,仍会执行初始化代码块。
如果一个非抽象类没有申明任何主、次构造函数,默认会生成一个不带参的主构造函数。
函数的可见性为public。如果不想类有一个公有构造函数,需要声明一个private的主构造函数。1
class TestClass private constructor () {}
在JVM上,如果主构造函数中的所有参数都有默认值,则会默认生成一个额外的无参构造函数,它将使用默认值。
创建类的实例
kotlin 在创建实例时,不需要new 关键字1
2class MyPerson(str: String, var age: Int) {}
var person = MyPerson("jack", 11);
类成员
- 构造函数与初始化代码块
- 函数
- 属性
- 嵌套类、内部类
- 对象申明
继承
在kotlin中,所有类都有一个超类 Any,这对于没有超类型声明的类是默认超类:
var oneClass; // 从Any隐式继承
Any 类中有三个方法 equas()、 hashcode()、 toString(), 因此所有kotlin类都定义有这三个方法
默认情况下,kotlin中类都是final 的,不可被继承,如果需要声明该类可以被继承,需要使用关键字 open。
并且kotlin中是使用 : 来表示继承。
1 | open class TestClassSuper {} |
如果超类中有声明主构造函数,
则子类可以声明主构造函数,则并必须用子类中主构造函数参数初始化超类。
如果子类没有声明主构造函数,则必须声明次级构造函数,并且使用super初始化基类1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19open class MyPerson(str: String, var age: Int) {
var name = str;
var tall:Double? = null;
init {
println("init test ${name}");
}
constructor(str: String, age: Int, tall: Double?):this(str, age) {
this.tall = tall;
}
}
class TestPerson(str: String, age: Int) : MyPerson(str, age) {}
class Test2 : MyPerson {
constructor(str: String, age: Int):super(str, age);
constructor(str: String, age: Int, tall: Double?): super(str, age, tall);
}
函数的重写
正如类的继承需要申明open标识该类开放继承,
类中的函数标识可以被重写也是需要使用open申明,如果没有函数没有申明open,
则在子类中不允许出现同名并且同参数类型的函数。
出现同名但不同参数的函数时允许的,正如java中的重载
1 | open class MyPerson(str: String, var age: Int) { |
属性的重写
同函数的重写,属性的重写也是需要使用open标识,并在子类中使用override1
2
3
4open var i = 2;
// childClass
override var i = 4;
在属性的重写中,有一点需要注意,
可以用var 重写val,却不能用val重写var;这一点是和java不一样的。
因为用val申明的属性本质上申明了get方法,而将其重写为var只是在子类新增了一个set方法
派生类的初始化顺序
1、进入子类的构造函数
2、进入父类的构造函数并完成初始化
3、进入父类的init代码块
4、父类中属性的初始化
5、子类构造函数完成初始化
6、子类init代码块
7、子类属性初始化
调用父类方法或属性
可以使用super关键字1
2
3
4// 方法
super.method();
// 属性
super.nema;
内部类中调用外部类父类属性或方法,使用super@Outer1
super@OutClass.method();