10. 类和对象

类的属性可以使用 var 声明变量,可以使用 val 声明常量。
属性的引用可以用 (.)符号来实现。
属性取值和赋值的 getter 和 setter 都是可选的 。
val 不允许设置 setter 函数,它是只读的。

class Person{
    var lastName :String = "zhang"
    get() = field.toUpperCase()     //转换为大写
    set

    var no: Int = 100
    get
    set(value) {
        if (value < 10) {
            field = value
        }else{
            field = -1
        }
    }

    var height:Float = 145.4f
    private set

    fun addOne(x: Float) {
        height += x
    }
}

这个 Person 类的 height 把 setter 设置为私有的,外部不能直接修改,需要通过 Person 类提供的方法来修改。这里提供了 addOne 方法。

    var person :Person = Person()
    person.lastName = "wang"
    println("lastName is ${person.lastName}")

    person.no = 9
    println("no is ${person.no}")

    person.no = 20
    println("no is ${person.no}")

    println("height is ${person.height}")
    person.addOne(1f)
    println("height is ${person.height}")

在 main 里实现这些代码,对 Person 类做相应的访问。
运行结果

lastName is WANG
no is 9
no is -1
height is 145.4
height is 146.4
类的构造器

Kotlin 的类是通过 constructor 来实现构造器的。构造器有主构造器和次构造器之分。
主构造器中不能包含任何代码,初始化代码可以放在 init 初始化代码段中。

class Pp constructor(firstName: String){
    init {
        System.out.println("First name is $firstName.")
    }
}

这样在实例化的时候,会打印出一句话来

var p = Pp("Joel")
First name is Joel.

类的 constructor 关键字一般是可以省略的。如果主构造函数有注解或可见性修饰符,则 constructor 关键字不可省略,并且这些修饰符要放在 constructor 前面。
类也可以声明前缀有 constructor 的次构造函数。
当类有一个主构造函数,每个次构造函数需要委托给主构造函数,可以直接委托或通过别的次构造函数间接委托。委托到同一个类的另一个构造函数用 this 关键字。

class Person constructor(firstName: String){

    constructor(name: String, parent: Person): this(name){
        
    }
}

抽象类没有声明任何构造函数的,会有一个生成的不带参数的主构造函数。构造函数的默认可见性是 public 。如果不希望类有这个公有构造函数,则需要声明一个带有非默认可见性的空的主构造函数。

class DontCreateme private constructor(){

}

再看一个类的示例

package main

fun main(args: Array<String>) {
    val cofox = Cofox("金龙翼移动办公", 1000)
    println(cofox.Sitename)
    println(cofox.Url)
    println(cofox.Country)
    cofox.PrintTest()
}

class Cofox constructor(name: String){
    //  大括号内是类体构成
    var Url: String = "http://www.cofox.com"
    var Country: String = "CN"
    var Sitename = name

    init {
        println("初始化网站名称:$name")
    }

    //  次构造函数
    constructor(name: String, alexa: Int): this(name){
        println("Alexa 排名 $alexa")
    }

    fun PrintTest(): Unit {
        println("我是类的函数")
    }
}

运行结果

初始化网站名称:金龙翼移动办公
Alexa 排名 1000
金龙翼移动办公
http://www.cofox.com
CN
我是类的函数
继承类

Kotlin 默认类都是 final 的。如果类需要被其他类继承,那么要让这个类 open 才行。
当 fun 是 open 的时候,那么也是可以被 override 的。

open class Base{
    open fun f(){}
}

abstract class Derived :Base(){
    override abstract fun f()
}

由于 Base 类是 open 的,所以 Derived 可以继承 Base 。
由于 f() 是 open 的,所以可以被 override

嵌套类

类可以嵌套其他类
当要引用类内的函数时,类后需要跟括号

class Outer{
    private val bar : Int = 1
    class Nested{
        fun foo() = 2
        class Thrd{
            fun mee() = "meyaya"
        }
    }
}

在 main 函数中这样调用 Outer 里的类和函数

    val demo = Outer.Nested().foo()
    val demo2 = Outer.Nested.Thrd().mee()
    println(demo.toString() + ":" + demo2)

执行结果如下

2:meyaya
内部类

当把嵌套在内部的类标记为 inner 内部类时,每层的引用都需要加括号。
内部类可以访问外部类成员,也可以通过 this@外部类 ,从而达到能获取外部类实例的使用模式。

class Outer{
    private val bar : Int = 1
    inner class Nested{
        fun foo() = bar     //访问外部类成员
        inner class Thrd{
            fun mee() = "meyaya"
            fun innerTest(){
                var o = this@Outer
                println("这是获取外部类成员" + o.bar.toString())
//                bar
            }
        }
    }
}

在 main 中可以这样调用

    val demo = Outer().Nested().foo()
    val demo2 = Outer().Nested().Thrd().mee()
    println(demo.toString() + ":" + demo2)
    Outer().Nested().Thrd().innerTest()

运行结果

1:meyaya
这是获取外部类成员1

不仅如此,class 中的 o 可以像在 main 中一样调用 class 里的函数。

匿名内部类

使用对象表达式来创建匿名内部类
首先定义一个接口,接口内是一个 test() 函数

/*
* 定义接口
* */
interface TestInterFace{
    fun test()
}

创建一个 Test 类,类内有一个 成员 v 和一个函数,函数的参数为 TestInterFace 接口。

class Test{
    var v = "成员属性"
    fun setInterFace(test: TestInterFace){
        test.test()
    }
}

在主函数中,先声明实例化这个Test类。
试着打印一下这个类的成员 v,看是否能成功。

var test = Test()
println(test.v)

类实例 test 的 setInterFace 函数的参数是接口,这里用对象表达式来创建接口对象,即匿名内部类的实现。

    test.setInterFace(object: TestInterFace{
        override fun test() {
            println("对象表达式创建匿名内部类的实例")
        }
    })
类的修饰符

类的修饰符包括:类属性修饰符(classModifier)和 访问权限修饰符(accessModifier)

  • classModifier: 类属性修饰符,标示类本身特性。
abstract 抽象类
final 类不可继承,默认属性
enum 枚举类
open 类可继承,非默认属性,需要注意
annotation 注解类
  • accessModifier: 访问权限修饰符
private 定义的内部可见
protected 同一个文件中或子类可见
public 所有调用的地方都可见
internal 同一个模块中可见
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容

  • 类和对象 类是对一类事物的描述,对象是类的实例。在面向对象编程思想中一切事物都是对象,类和对象是面向对象编程的重要...
    Stone_Zhuo阅读 1,211评论 0 0
  • 面向对象编程(OOP) 在前面的章节中,我们学习了Kotlin的语言基础知识、类型系统、集合类以及泛型相关的知识。...
    Tenderness4阅读 4,354评论 1 6
  • 写在开头:本人打算开始写一个Kotlin系列的教程,一是使自己记忆和理解的更加深刻,二是可以分享给同样想学习Kot...
    胡奚冰阅读 1,369评论 5 11
  • Kotlin的类和接口与Java的类和接口是有一定的区别的。Kotlin的接口是可以包含属性声明。Kotlin默认...
    程自舟阅读 10,246评论 0 11
  • 如果描述的类型不是基本类型怎么办? 任何复杂的数据类型都是由基本的数据类型构成的 面向对象 使用基本数据类型描述复...
    JunChow520阅读 2,152评论 0 1