美文网首页
类与构造函数

类与构造函数

作者: codergege | 来源:发表于2018-11-21 22:05 被阅读0次

回到目录
项目源码 kotlin-class 项目


类声明

Kotlin 中用 class 关键字声明一个类, 跟 java 有区别的一些地方是, 你可以在同个
源文件中声明多个 public 类; 如果一个类没有 body, 那个花括号是可以省略的(比如
spring boot 中的启动类, 只是用来放注解 @SpringBootApplication);

@SpringBootApplication
class KotlinClassApplication

构造函数

在 Kotlin 中的一个类可以有一个主构造函数以及一个或多个次构造函数。主构造函数是
类头的一部分.

// 主构造函数中不加 var, val, 那么 name 和 age 只是构造函数的参数而已
class Animal constructor(name: String, age:Int?)

注意, 如果构造函数参数不加 valvar, kotlin 编译器不会将他们当成类属性, 即
不会自动生成 getter setter 方法. 所以一般都要加上 val.

// 如果不加 var, val
// 需要再写一下属性初始化代码才行
class Dog (name: String, age: Int?) {
    val name = name
    val age = age
    // 属性必须初始化, 除非使用 lateinit var 标记为延迟初始化的属性
    lateinit var owner: String
}

如果属性不写在主构造函数中, 那就必须初始化; 除非加上 lateinit var 标记

新建一个对象不需要使用 new 关键字, 直接调用构造函数就可以了.

    @Test fun testConstruct() {
        val person = Person("codergege", null)
        assertEquals("codergege", person.name)
        assertNull(person.age)
    }

可以看到, 虽然我们并没有写 getter setter 方法, 但是已经可访问属性了, 因为 kotlin
编译器已经自动为我们生成.

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

class Person(val name: String, val age: Int?)

如果需要在构造函数中写点逻辑, 得用 init 块. 例如:

class Person(val name: String, val age: Int?) {
    init {
        require(name.trim().length > 0) {
            "名称长度必须大于 0 !"
        }
        if(age != null) {
            require(age > 0 && age < 150) {
                "年龄必须是 (0, 150) 之间"
            }
        }
    }
}

一个对象的初始化过程里, 多个 init 块和属性初始化代码是按代码顺序执行的

class InitOrderDemo(name: String) {
    val firstProperty = "First property: $name".also(::println)
    
    init {
        println("First initializer block that prints ${name}")
    }
    
    val secondProperty = "Second property: ${name.length}".also(::println)
    
    init {
        println("Second initializer block that prints ${name.length}")
    }
}

"xxx".also() 会将调用传入的函数, 参数是 this(谁调就传谁) 并返回 this
测试这段代码:

    @Test fun testInitOrder() {
        val obj = InitOrderDemo("hello")
    }

输出是

First property: hello
First initializer block that prints hello
Second property: 5
Second initializer block that prints 5

注意到, name 这个构造函数的参数也能被用来给属性赋值.这是因为编译器最终会将所
有的 init 和属性初始化代码放进主构造函数中.

次构造函数

次构造函数通过 constructor 声明.
次构造函数(Secondary Constructor)必须通过 this 调用主构造函数, 然后把参数传过去:
当然, 如果没有主构造函数, 也可以用 this 调用其他次构造函数.

    // 非主构造函数中, 参数不允许有 val 和 var, 就像普通函数那样.
    constructor(name: String): this(name, null)

现在通过第二个构造函数创建一个对象:

        val jack = Person("Jack")
        assertEquals("Jack", jack.name)
        assertNull(jack.age)

Kotlin 中所有默认访问级别是 public 的.

如果一个类的主构造函数中所有的属性都有默认值, 那么编译器会自动再生成一个无参
的构造函数, 方便在 Spring, JPA 等框架中使用.
以前是需要加上 no-arg 插件的, 现在这个插件不是必须的了.


回到目录

相关文章

  • ES6面向对象

    类声明与构造函数 class 声明类constructor 构造函数 继承与超类

  • 【Dart】Dart类与对象

    类与对象 类 继承 抽象类 接口 混入 泛型 枚举类类-简介 构造器 (构造函数) 默认构造函数与类同名的函数,在...

  • C# 构造函数总结

    构造函数 构造函数分为:实例构造函数,静态构造函数,私有构造函数。 实例构造函数 1、构造函数的名字与类名相同。 ...

  • C++基础构造函数(constructor)

    构造函数定义 C++中的类可以定义与类名相同的特殊成员函数,这种与类名相同的成员函数叫做构造函数,构造函数在定义时...

  • Dart---构造函数与命名构造构造函数(初始化)

    构造函数(初始化) 构造函数:构造函数与类名相同,构造函数又叫初始化函数,当类被创建的时候,会自动调用。Dart相...

  • C#魔帅-lesson_01-类

    类的定义 构造函数 类的 构造函数 是类的一个特殊的成员函数,当创建类的新对象时执行。构造函数的名称与类的名称完全...

  • 【Boolan】 C++类构造函数 、析构函数和拷贝构造函数

    类的构造函数 类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。 构造函数的名称与类的名称是完...

  • 类的构造函数

    1.类的构造函数 类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。 构造函数的名称与类的名称...

  • 我的JS笔记 -- 类

    JS是没有类的,但JS可以利用构造函数实现近似类的功能。 构造函数 构造函数,是用来创建对象的函数。与普通的函数声...

  • [初学C++]构造和析构函数

    什么是构造函数定义C++中的类可以定义与类名相同的特殊成员函数,这种与类名相同的成员函数叫做构造函数.C++对类提...

网友评论

      本文标题:类与构造函数

      本文链接:https://www.haomeiwen.com/subject/bivhqqtx.html