前言
kotlin的类和Java的类有很大的区别,也是kotlin学习的一个重点,下面开始介绍kotlin的类及其相关的的知识点。
一.类&成员变量&方法
1.1 访问权限修饰符
熟悉Java的朋友应该知道Java有这些访问权限修饰符:private,default(缺省),protected,public。
以下是Java访问权限修饰符表格:
访问权限修饰符 | 同一类 | 同一包 | 子类 | 任意地方 |
---|---|---|---|---|
private | 是 | 否 | 否 | 否 |
default(缺省) | 是 | 是 | 否 | 否 |
protected | 是 | 是 | 是 | 否 |
public | 是 | 是 | 是 | 是 |
(是:可以访问,否:不可以访问) |
那么对于kotlin访问权限修饰符又是如何的呢?
在kotlin中将default(缺省)改为public,并且增加了internal,其他的则是和Java一样。
以下是kotlin访问权限修饰符表格:
访问权限修饰符 | 同一类 | 同一包 | 子类 | 同一模块 | 任意地方 |
---|---|---|---|---|---|
private | 是 | 否 | 否 | 否 | 否 |
protected | 是 | 是 | 是 | 否 | 否 |
internal | 是 | 是 | 是 | 是 | 否 |
public(缺省) | 是 | 是 | 是 | 是 | 是 |
对于class的修饰符需要着重说一下:
- internal,该修饰符限定的范围是一个模块(module),所谓的模块你可以认为是一个组件,一个第三方支持包,而被internal修饰的变量或者类不能被其他模块(module)所使用。
- class类在默认情况下(不加任何修饰符)都是
public final
的,这就说明在默认情况下,1.类是公开可以被其他类所访问;2.还有就是该类是不可以被继承的。
1.2 类和对象
下面是一个最简单的类
// 定义了一个Person类
// kotlin默认访问权限修饰符就是public
class Person {
}
fun main(){
val person = Person() // 创建一个Person对象
// val person0:Person = Person() // 带类型的声明
println(person) // person对象
}
kotlin的创建对象相对于Java要简单的多,连new关键字都不需要写。
1.3 成员变量和成员方法
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");
}
输出:
Jack
23
1001
eat rice
上面的代码例子中无论是成员变量,还是成员方法都是public的,所以在main函数中可以直接调用。读者也可以试着改为private来修饰。
二.构造函数
kotlin的构造函数和Java的构造函数差距还是挺大的,kotlin的构造函数主要分为主构造函数和次构造函数,下面将逐一介绍一下。
2.1 主构造函数
Kotlin和Java一样,有不带参数的默认构造函数。如果指明了参数,那么一般写法如下所示:
带参数的主构造函数的一般写法是这样的:
// 自动创建同名的成员变量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
上面的代码有几点需要注意:
constructor(var name:String, var age:Int)
就是该类的主构造函数。constructor
关键字可以省略。- 其中的
var name:String, var age:Int
会在该类中自动创建同名的成员变量(val
修饰的也一样),初始化的值就是该构造函数的参数值。 - 对于主构造函数的参数
var name:String, var age:Int
。如果不加var
,则不会创建同名的成员变量,而仅仅代表函数的参数。
写过Java的都知道,Java的类可以在构造函数的函数体中初始化:
public class Person {
public Person() {
// 构造函数的函数体,这个可以省略
}
}
那么Kotlin是否也有类似的功能呢?答案是有的!这就需要介绍Kotlin的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}")
}
上面的例子就是对init{}
的使用,你可以在init{}
中实现对类的初始化功能,就和使用Java的构造函数的函数体一样。
前面说到,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}")
}
既然主构造函数可以加上访问权限修饰符,那么成员变量name和age也是可以加上:
// 相当于成员变量name和age设置为private
class Person constructor(private var name:String, private var age:Int){
}
fun main(){
val person = Person("Jack", 23)
// 由于成员变量name和age设置为private,所以这里报错
println("name is ${person.name} age is ${person.age}")
}
以上就是主构造函数的使用方法,通过上面的示例可以总接一句话,Kotlin中,主构造函数就是类的入口。
2.2 次构造函数
对于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}")
}
和主构造函数一样,次构造函数前面也可以加上访问权限修饰符。
对于次构造函数有一个相当重要的规则,就是次构造函数必须直接或者间接调用主构造函数
下面代码就是一个错误的示范:
class Person (var name:String, var age:Int){
// 次构造函数
constructor(name: String):this(name, 22)
// 次构造函数
constructor(age: Int) // 报错
}
如果次构造函数不调用主构造函数,会抛出这个错误Primary constructor call expected
三.this关键字
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
this还有一种用法就是带限定符的,this@xxx
这种用法主要用于匿名类和内部类,后面在介绍匿名类和内部类的时候再补充。
结束
以上就是关于kotlin的类,构造函数,对象的简单使用和介绍,欢迎指正错误和分享。