本文介绍: 前面粗咯的讲了类,这篇详细介绍类及相关概念定义使用关键字声明由(指定类型参数、主构造函数等)和由{}包围的组成。类头和类体都是可选的;如果类没有体,可以省略

前面粗咯的讲了类,这篇详细介绍类及相关概念

定义类使用关键字class

class Person { /*...*/ }

声明类名类头指定类型参数、主构造函数等)和由{}包围的类体组成。类头和类体都是可选的;如果类没有体,可以省略{}

class Empty

构造函数(Constructors

kotlin中,一个类有一个构造函数零个或多个构造函数。主构造函数类头声明,它位于类名和可选类型参数之后

class Person constructor(firstName: String) { /*...*/ }

如果主构造函数没有任何注解或可见性修饰符可以省略constructor关键字

class Person(firstName: String) { /*...*/ }

构造函数在类头中初始化实例及其属性。类头不能包含任何可运行代码。如果你想在创建对象运行一些代码,可以在类体内使用初始化块。初始化块是用init关键字声明的,后面跟着花括号。在花括号内编写你想要运行的任何代码

实例初始化期间,初始化块按照它们在类体中出现的顺序执行,与属性初始化器交错

class InitOrderDemo(name: String) {
    val firstProperty = "第一个属性: $name".also(::println)

    init {
        println("第一个init$name")
    }

    val secondProperty = "第二个属性: ${name.length}".also(::println)

    init {
        println("第二个init${name.length}")
    }
}
fun main(){
    InitOrderDemo("张三")
//    第一个属性 张三
//    第一个init块 张三 
//    第二个属性: 2
//    第二个init块 2
}

构造函数参数可以在初始化块中使用。它们也可以在类体中声明的属性初始化中使用

class Customer(name: String) {
    val customerKey = name.uppercase()
}

kotlin有一种简洁语法用于声明属性并从主构造函数中初始化它们,声明也可以包括类属性默认值

class Person(val firstName: String, val lastName: String, var isEmployed: Boolean = true)

就像常规属性一样,主构造函数中声明的属性可以是可变var只读val

如果构造函数注解或可见性修饰符constructor关键字是必需的,修饰符位于它之前

class Customer public @Inject constructor(name: String) { /*...*/ }

次构造函数

一个类也可以声明次要构造函数,它们以constructor前缀

class Person(val pets: MutableList<Pet&gt; = mutableListOf())

class Pet {
    constructor(owner: Person) {
        owner.pets.add(this)
    }
}

如果类有主构造函数,则每个次要构造函数需要直接间接地通过一个次要构造函数将其委托给主构造函数。使用this关键字完成对同一类的另一个构造函数委托

class Person(val name: String) {
    val children: MutableList<Person> = mutableListOf()
    
    constructor(name: String, parent: Person) : this(name) {    // 委托主构造函数
        parent.children.add(this)
    }
}

初始化块中的代码实际上成为主构造函数的一部分。在访问次要构造函数的第一条语句时,将委托给主构造函数,因此在次要构造函数的主体之前执行所有初始化块和属性初始化器中的代码

即使类没有主构造函数,委托仍然会隐式发生,并且仍会执行初始化块

class Constructors {
    init {
        println("Init block")
    }

    constructor(i: Int) {
        println("Constructor $i")
    }
}

fun main(){
    Constructors(1)
}
//    Init block
//    Constructor 1

如果没有定义任何构造函数,则会自动生成一个public修饰的无参主构造函数

如果不想要有一个public修饰的无参构造函数,需要手动定义一个private修饰的构造函数

class DontCreateMe private constructor(){
}

fun main(){
    val dontCreateMe = DontCreateMe()  // 报错 - Cannot access '<init>': it is private in 'DontCreateMe'
}

当所有主构造函数参数具有默认值时,在JVM上,编译器生成一个额外的无参数构造函数,该构造函数将使用默认值。这使得使用Kotlin与创建通过参数构造函数的类实例的库(例如Jackson或JPA)更容易。

class Customer(val customerName: String = "")

创建实例

创建一个实例调用一个方法一样简单

class Customer(var username: String) {
}

fun main() {
    val customer = Customer("Joe Smith")
}

kotlin中创建实例需要new

成员

继承

篇文章讲解

抽象类

使用abstract关键字定义一个抽象类以及所有或者部分类成员抽象成员类中没有被实现

abstract class Polygon {
   abstract fun draw() // 未实现方法
}

class Rectangle : Polygon() {   // 继承Polygon类,实现deaw方法
   override fun draw() {
       // 方法实现
   }
}

如果是一个非抽象类或者方法,如果想要被重写或者继承,则需要使用open关键字修饰

open class Polygon {
    open fun draw() {
        // some default polygon drawing method
    }
}

abstract class WildShape : Polygon() {
    abstract override fun draw()
}

抽象方法可以重新非抽象方法

伴生对象

在没有类实例的情况下,通过类名调用该类内部对象声明的成员,可以定义伴生对象实现

原文地址:https://blog.csdn.net/qq_40104261/article/details/134601539

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_23618.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注