Kotlin 类和对象 | 菜鸟教程

定义

Kotlin类中可以包括:构造函数、初始代码块、方法、属性、内部类

类的属性

  1. class Runoob {
  2. var name: String = ……
  3. var url: String = ……
  4. var city: String = ……
  5. }

在Kotlin中,没有 new 关键字
val site = Runoob()

构造器

Kotlin 中的类可以有一个 主构造器,以及一个或多个次构造器,主构造器是类头部的一部分,位于类名称之后
class Person constructor(firstName: String) {}
如果主构造器没有任何注解,也没有任何可见度修饰符,那么constructor关键字可以省略。
class Person(firstName: String) { }

getter和setter

声明属性时候的完整写法:

  1. var <propertyName>[: <PropertyType>] [= <property_initializer>]
  2. [<getter>]
  3. [<setter>]

在kotlin中,getter和setter都是可选的

  1. class Person {
  2. var lastName: String = "zhang"
  3. get() = field.toUpperCase() // 将变量赋值后转换为大写
  4. set
  5. var no: Int = 100
  6. get() = field // 后端变量
  7. set(value) {
  8. if (value < 10) { // 如果传入的值小于 10 返回该值
  9. field = value
  10. } else {
  11. field = -1 // 如果传入的值大于等于 10 返回 -1
  12. }
  13. }
  14. var heiht: Float = 145.4f
  15. private set
  16. }
  17. // 测试
  18. fun main(args: Array<String>) {
  19. var person: Person = Person()
  20. person.lastName = "wang"
  21. println("lastName:${person.lastName}")
  22. person.no = 9
  23. println("no:${person.no}")
  24. person.no = 20
  25. println("no:${person.no}")
  26. }

kotlin中,类是不能有字段的。
提供了后端变量的机制,后端变量使用field关键字进行声明

  1. var no: Int = 100
  2. get() = field // 后端变量
  3. set(value) {
  4. if (value < 10) { // 如果传入的值小于 10 返回该值
  5. field = value
  6. } else {
  7. field = -1 // 如果传入的值大于等于 10 返回 -1
  8. }
  9. }

初始代码块

主构造器中不能包含任何的代码,初始化代码可以放在初始化代码段中
初始化代码段使用init关键字作为前缀

  1. class Person constructor(firstName: String) {
  2. init {
  3. println("FirstName is $firstName")
  4. }
  5. }

实例

  1. class Runoob constructor(name: String) { // 类名为 Runoob
  2. // 大括号内是类体构成
  3. var url: String = "http://www.runoob.com"
  4. var country: String = "CN"
  5. var siteName = name
  6. init {
  7. println("初始化网站名: ${name}")
  8. }
  9. fun printTest() {
  10. println("我是类的函数")
  11. }
  12. }
  13. fun main(args: Array<String>) {
  14. val runoob = Runoob("菜鸟教程")
  15. println(runoob.siteName)
  16. println(runoob.url)
  17. println(runoob.country)
  18. runoob.printTest()
  19. }

次构造函数

类也可以有二级构造函数,需要加前缀 constructor

  1. class Person {
  2. constructor(parent: Person) {
  3. parent.children.add(this)
  4. }
  5. }

如果类有主构造函数,每个次构造函数都要,或直接或间接通过另一个次构造函数代理主构造函数。在同一个类中代理另一个构造函数使用 this 关键字:

  1. class Person(val name: String) {
  2. constructor (name: String, age:Int) : this(name) {
  3. // 初始化...
  4. }
  5. }

抽象类

抽象是面向对象编程的特征之一,类本身,或类中的部分成员,都可以声明为abstract的。抽象成员在类中不存在具体的实现。

  1. abstract class Class1 {
  2. abstract fun test()
  3. }
  4. class Class2 : Class1() {
  5. override fun test() {
  6. println("test")
  7. }
  8. }

嵌套类

我们可以把类嵌套在其他类中,看以下实例:

  1. class Outer { // 外部类
  2. private val bar: Int = 1
  3. class Nested { // 嵌套类
  4. fun foo() = 2
  5. }
  6. }
  7. fun main(args: Array<String>) {
  8. val demo = Outer.Nested().foo() // 调用格式:外部类.嵌套类.嵌套类方法/属性
  9. println(demo) // == 2
  10. }

内部类

内部类使用 inner 关键字来表示。
内部类会带有一个对外部类的对象的引用,所以内部类可以访问外部类成员属性和成员函数。

  1. class Outer {
  2. private val bar: Int = 1
  3. var v = "成员属性"
  4. /**嵌套内部类**/
  5. inner class Inner {
  6. fun foo() = bar // 访问外部类成员
  7. fun innerTest() {
  8. var o = this@Outer //获取外部类的成员变量
  9. println("内部类可以引用外部类的成员,例如:" + o.v)
  10. }
  11. }
  12. }
  13. fun main(args: Array<String>) {
  14. val demo = Outer().Inner().foo()
  15. println(demo) // 1
  16. val demo2 = Outer().Inner().innerTest()
  17. println(demo2) // 内部类可以引用外部类的成员,例如:成员属性
  18. }

类的修饰符

  • classModifier:类、属性修饰符

    1. abstract // 抽象类
    2. final // 类不可继承,默认属性
    3. enum // 枚举类
    4. open // 类可继承,类默认是final的
    5. annotation // 注解类
  • accessModifier:访问权限修饰符

    1. private // 仅在同一个文件中可见
    2. protected // 同一个文件中或子类可见
    3. public // 所有调用的地方都可见
    4. internal // 同一个模块中可见