在工作中用到kotlin,发现类的创建,单例,构造函数,创建对象和java有很多不同。
这些是kotlin学习的基础,下面开始介绍kotlin的类及其相关的的知识点。
Java有这些访问权限修饰符:private,default(缺省),protected,public。
kotlin访问权限修饰符又是如何的呢?
以下是kotlin访问权限修饰符表格:
internal:该修饰符限定的范围是一个模块(module),所谓的模块你可以认为是一个组件,一个第三方支持包,而被internal修饰的变量或者类不能被其他模块(module)所使用。
class类在默认情况下(不加任何修饰符)都是public final的,这就说明在默认情况下:
1.类是公开可以被其他类所访问;
2.还有就是该类是不可以被继承的。
?
// 定义了一个Person类
// kotlin默认访问权限修饰符就是public
class Person {
}
fun main(){
val person = Person() // 创建一个Person对象
// val person0:Person = Person() // 带类型的声明
println(person) // person对象
}
class Person {
// 成员变量
var name:String = "Jack"
var age:Int = 23
// 只读
val id = 1001
// 成员函数
fun eat(food:String){
println("eat $food")
}
}
fun main(){
val person = Person()
// var person = Person() // 创建一个只读的Person对象
println(person.name)
println(person.age)
println(person.id)
person.eat("rice");
}
????????kotlin的构造函数主要分为主构造函数和次构造函数
带参数的主构造函数的一般写法是这样的:
// 自动创建同名的成员变量name和age,同时默认是public属性的
class Person constructor(var name:String, var age:Int){
}
fun main(){
val person = Person("Jack", 23)
println("name is ${person.name} age is ${person.age}")
}
输出 : name is Jack age is 23
注意点:
1、constructor(var name:String, var age:Int)
就是该类的主构造函数。constructor
关键字可以省略。
2、var name:String, var age:Int
会在该类中自动创建同名的成员变量(val
修饰的也一样),初始化的值就是该构造函数的参数值。
3、对于主构造函数的参数var name:String, var age:Int
。如果不加var
,则不会创建同名的成员变量,而仅仅代表函数的参数。
java中可以在构造函数中初始化一些参数或者做一些逻辑。
public class Person {
public Person() {
// 构造函数的函数体,这个可以省略
}
}
那么Kotlin是否也有类似的功能呢?答案是有的!这就需要介绍
Kotlin的init{}
的用法了。
???init{}
class Person constructor(name:String, age:Int){
// 成员变量
var mName:String = ""
var mAge:Int = -1;
// init代码块
init {
// 类似Java构造函数体
mName = name
mAge = age
// 其他的初始化过程
}
}
fun main(){
val person = Person("Jack", 23)
println("name is ${person.mName} age is ${person.mAge}")
}
前面说到,Kotlin为了简化主构造函数代码,constructor
做为关键字是可以省略的:
class Person(var name:String, var age:Int){
}
?
当然,主构造函数的constructor
关键字也不是没有用,当你需要对构造函数,加上访问权限修饰的时候,就需要加上constructor
。
// 直接将构造函数修饰为private
class Person private constructor(var name:String, var age:Int){
}
fun main(){
// 由于设置构造函数为privae,无法创建对象。
val person = Person("Jack", 23) // 报错
println("name is ${person.name} age is ${person.age}")
}
那怎么调用呢?
可以使用伴生对象(companion object)来创建该类的实例。
class MyClass {
// Private constructor
private constructor() {}
companion object {
fun createInstance(): MyClass {
return MyClass()
}
}
}
// 通过伴生对象的createInstance()方法来获取MyClass的实例
val instance = MyClass.createInstance()
Java我们知道,构造函数是可以重载的,kotlin也一样,存在构造函数的重载,这就是次构造函数。
class Person (var name:String, var age:Int){
// 次构造函数
constructor(name: String):this(name, 22)
// 次构造函数
constructor(age: Int):this("Jack", age)
// private constructor(age: Int):this("Jack", age)
}
fun main(){
val person0 = Person("Jack")
println("name is ${person0.name} age is ${person0.age}")
val person1 = Person(23)
println("name is ${person1.name} age is ${person1.age}")
}
规则,就是次构造函数必须直接或者间接调用主构造函数
这里this指向主构造函数。
this
关键字代表当前类的对象。(也可用于指向主构造函数)
/**
* 这里的this都代表当前类的对象
*/
class Person (name:String, age:Int){
var name:String = "name"
var age:Int = 22
init {
this.name = name
this.age = age
}
fun selfIntroduce(){
// 这里也可以省略this
println("I am ${this.name}, ${this.age} years old")
}
}
fun main(){
val person = Person("Jack", 23)
person.selfIntroduce()
}
//
输出 : I am Jack, 23 years old
his还有一种用法就是带限定符的,this@xxx
这种用法主要用于匿名类和内部类,后面在介绍匿名类和内部类的时候再补充。这块我理解有点乱,什么闭包之类的。后续理清楚了再写一篇。