Kotlin学习之路(四):类,构造函数,对象

前言

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的修饰符需要着重说一下:

  1. internal,该修饰符限定的范围是一个模块(module),所谓的模块你可以认为是一个组件,一个第三方支持包,而被internal修饰的变量或者类不能被其他模块(module)所使用。
  2. 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

上面的代码有几点需要注意:

  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的都知道,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的类,构造函数,对象的简单使用和介绍,欢迎指正错误和分享。

猜你喜欢

转载自blog.csdn.net/RQ997832/article/details/122890951
今日推荐