侧边栏壁纸
  • 累计撰写 416 篇文章
  • 累计创建 65 个标签
  • 累计收到 145 条评论

目 录CONTENT

文章目录

Kotlin学习笔记-类的基本介绍和创建方法

Z同学
2021-07-09 / 0 评论 / 1 点赞 / 2,217 阅读 / 5,307 字
温馨提示:
本文最后更新于 2021-12-16,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

Kotlin 类和对象

介绍:在Kotlin中类可以包含:构造函数和初始化代码块,函数,属性,内部类,对象声明. 使用的关键字和java是一样的使用class进行声明

实例:

class Demo2 { //类名为Demo2
    //类里面的 函数,属性,内部类,声明等
    fun foo(){ //创建成员函数
        print("Foo")
    }
}

如果是对js有点熟悉的同学,应该对fun指令很眼熟

类似于js的function 关键字.

构造方法

介绍: Kotlin之中一个类可以有一个主构造器以及多个次构造器.

实例:

class Person constructor(firstName:String){
	init{
         //主构造函数,创建后会执行该方法   
     }
	
}

其中关于constructor关键字在主构造器之中一般是可以省略的

其他的子构造器之中需要添加该关键字进行定义

如果一个类有主构造器(ps:类名后面添加了括号).那么每个子构造器都要直接或者间接使用主构造器.也就是使用this关键字代理主构造器方法.

实例1:

//创建了空值传递的主构造器
class Demo3(){
    //子构造器就必须加上 this()
    constructor(name:String):this(){
    }
}

class Demo4{
    constructor(name:String){
        println("name:${name}")
    }
}
//定义构造方法 私有 不允许有公共的构造函数
class Demo5 private constructor(){
    
}

实例2:

class Person(firstName: String) {

    init {
        println("firstName:${firstName}")
    }

    constructor(firstName: String, url: String) : this(firstName) {
        println("url:${url}")
    }

    constructor(name: String, time: Int) : this(name) {
        println("Time:${time}")
    }
}


fun main(array: Array<String>) {
    //Kotlin之中 创建对象 没有New关键字
    var person1 = Person("Z同学")
    var person = Person("Z同学", "https://zinyan.com/")
    var person2 = Person("Z同学", 123)

}

输出结果:

firstName:Z同学  
firstName:Z同学
url:https://zinyan.com/
firstName:Z同学
Time:123

其实本质和java 的构造函数以及冲突检测是差不多的.不能允许相同传参的构造函数

只是相对于java的构造函数,Kotlin有一个主构造器的概念相对于java对构造函数的控制性更强而已.

如果我们要在主构造器创建时进行初始化操作,那么我们直接在init{}函数里面实现我们的逻辑即可.

其他情况:如果我们需要将构造器之中的函数定义为类的全局属性

很简单,添加上var 就能够在类的其他函数之中调用了

实例:

class Person(var firstName: String) {
    fun test() {
        firstName = "name"
    }
}

属性定义

介绍: 定义类的属性值,通常有两个关键字 分别是varval

var: 声明的属性是可以在之后函数调用之中进行修改的.

varl:声明的属性,在赋值之后是不能进行修改的. 你可以参照java 的final关键字修饰的属性.

实例:

class Demo2 { //类名为Demo2
    //类里面的 函数,属性,内部类,声明等   添加了?号才能允许null值存在.
    private var name: String? = null  //一样存在private 私有
    var url: String = ""
    var height: Int=0
    val max:Int =100
}

在Kotlin之中 创建对象时不用添加new字段.因为Kotlin之中没有new关键字.

实例:

fun  main(array: Array<String>){
    //Kotlin之中 创建对象 没有New关键字
    var temp=Demo2()
    temp.url="https://zinyan.com/"
    temp.height=170;
    temp.name="Z同学"
}

上面都是关于非空的属性定义.

如果我们要初始化时定义属性值空那么该如何处理?

Kotlin提供了一种可以延迟初始化的方案,使用lateinit 关键字来描述属性.

实例:

class Test(){
    lateinit var name: String

    fun setUp(value:String){
        name=value
    }
}

fun main(array: Array<String>) {
    var test = Test()
    test.setUp("Z同学")
    println("name:${test.name}")
}

输出:

name:Z同学

getter 和setter函数

介绍:通常情况下var定义的类都有默认的getersetter.如果定义为val标签额属性那么它将没有set函数

我们也可以根据需求,进行重构属性的gettersetter函数

实例1:

class Person() {
    var lastName: String = ""
        get() = field.uppercase()// 将变量赋值后转换为大写
}


fun main(array: Array<String>) {
    var person = Person()
    //针对lastName 参数进行了修改.
    person.lastName = "zinyan"
    //调用了lastName 的get方法会
    println("LastName:${person.lastName}")
}

输出:

LastName:ZINYAN

field 在方法之中的意思就是lastName. 因为getter,和setter之中 不能直接使用lastName

如果我们将方法替换后

实例2:

class Person() {
    var lastName: String = ""
        get() = lastName.uppercase()// 将变量赋值后转换为大写
}


fun main(array: Array<String>) {
    var person = Person()
    //针对lastName 参数进行了修改.
    person.lastName = "zinyan"
    //调用了lastName 的get方法会
    println("LastName:${person.lastName}")
}

输出:
image-20210709163159233

就会错误了.

在Kotlin之中,这个定义方式叫做BackingFields(后端变量). 使用field关键字声明.

field 关键词只能用于属性的访问器.也就是gettersetter函数里面

实例3:

class Person() {
    var no: Int = 100
        get() = field  //其实这个可以省略
        set(value) {
            if (value < 10) {  //如果传入的值小于 10 返回该值
                field = value
            } else {
                field = -1  // // 如果传入的值大于等于 10 赋值为-1
            }
        }
    var height: Float = 170.0f
        private set  //将属性的set方法设置为私有模式  外部禁止修改
}


fun main(array: Array<String>) {
    var person = Person()
    person.no = 9
    println("No:${person.no}")
    person.no =20
    println("No:${person.no}")

    println("Height:${person.height}")

输出:

No:9
No:-1
Height:170.0

关于getter 和setter 方法的基本情况就是这些了.

默认没有写的时候,Kotlin编译器会自动给我们补上. 例如下面的这种.

var dem: String = ""
    get() = field
    set(value) {
        field = value
    }

抽象类

介绍:抽象是面向对象编程特征之一.在Kotlin之中申明抽象类或者函数使用关键字abstract

定义概念和java 的抽象类和抽象方法一样.不用进行具体的实现.

实例:

abstract class Demo6 {
      open abstract fun text(str: String)
}

class dd : Demo6() {
    override fun text(str: String) {
        TODO("Not yet implemented")
    }
}

继承了Demo6 抽象类,所以需要实现里面的方法

抽象类默认情况下是public 的可以被直接继承.如果非抽象类我们需要'open'关键字进行标注,才能进行继承.

嵌套类

介绍:和java的嵌套类是一样的,我们可以在class里面写嵌套类.

实例:

class Demo7{
    private var name:String="ZZ"
    class TT{
        fun  text()=2
    }
}

fun main(array: Array<String>) {
    var demo =Demo7.TT();
    println("结果:${demo.text()}")
}

输出:

结果:2

内部类

介绍: 实现步骤和嵌套类是一样的,只是内部类添加了inner关键字进行修饰.

但是已经有嵌套类了.为什么还有一个内部类?

因为内部类会带有一个对外部类的对象的引用.所以内部类是可以直接访问外部类的属性和函数.

实例:

class Demo8 {
    private var name: String = "ZZ"

    inner class TT {
        fun nameStr()=name //可以直接获取外部类属性

        fun text() {
            println(this@Demo8.name)//通过注解得到外部类对象
        }
    }
}

fun main(array: Array<String>) {
    var demo = Demo8().TT() //这里有别于嵌套类的实现
    demo.text()
    println(  demo.nameStr())
}

输出:

ZZ

this后添加的@XXX 主要是为了消除歧义.因为嵌套类本身有自己的this.
加上@可以告诉编译器当前使用的外部类对象的this.

匿名内部类

介绍:使用对象表达式来创建匿名内部类:

实例:

class Demo9{
    var tt="随便的属性"
    fun setTT(test:TestInterFace){
        test.test()
        println(tt)
    }
}

interface TestInterFace{
    fun test()
}

fun main(array: Array<String>) {
    var test = Demo9();
    test.setTT(object  :TestInterFace{
        override fun test() {
            println("对象表达式创建匿名内部类的实例")
        }
    })
}

输出:

对象表达式创建匿名内部类的实例
随便的属性

其实匿名内部类,就如同我们在java 之中给函数传递对象时,我们直接new一个新对象传进去一样的.

只是Kotlin必须使用object关键字而已

修饰符

介绍:类的修饰符主要分为两个种类,一种是类属性修饰符(classModifier),一种是访问权限修饰符(accessModifier)

类属性修饰符: 标识类本身的特性

关键字介绍备注
abstract抽象类抽象类默认可以继承.不用额外添加open
final类不可以继承普通类默认不可被继承
enum枚举类
open类可以被继承添加标注之后就可以被继承了
annotation注解类

访问权限修饰符:标注类或者属性的访问权限

关键字介绍
private私有,仅当前类或同一个文件可访问
protected保护,在同一个类或者子类之中可访问
public公共,全部地方都可访问
internal内部,在同一个模块下可访问

Kotlin的关键字其实和java之中有很多的相识之处.特别是权限访问修饰符.

附录
上面例子的Demo代码。
https://zinyan.com/upload/2021/07/Demo2-488f5c987a294ab0bc96a25056781601.kt

1

评论区