美文网首页
Kotlin基础(类)

Kotlin基础(类)

作者: zhujunhua | 来源:发表于2018-04-28 10:06 被阅读0次

适合有java基础的,获取kotlin基础知识/语法等,Kotlin精讲-黑马程序员(原创)的学习笔记。

  1. Kotlin实现了默认的setter/getter方法,我们也可以对它们进行自定义,以及修改访问控制符。
  2. 主构函数
// Kotlin在类定义的时候,在类名后面加上小括号,变成了函数形式。
// 我们在小括号内就可以直接定义类创建的时候可以接收的值,并可以把接收的值赋值给变量,
// 达到Java里面构造函数的作用,我们称这样的函数为主构函数
class Person(name: String, age: Int) {
  var name: String = name
  var age: Int = age
}
// 在主构函数上,我们还可以为每一个变量加上一个val或者var修饰符
// 这样就表示,为该类定义了一个对应的成员属性
// 还可以给参数设置默认值
class Person2(var name: String="default_name", var age: Int=18) {
    fun printInfo() {
        println("name is $name, age is $age")
    }
}
fun main() {
    // Kotlin创建类对象的时候不需要使用new关键字
    val person = Person()
    // 主构函数,默认值的初始化
    val person21 = Person2()
    val person22 = Person2("Jerry")
    val person23 = Person2("Jerry", 4)
    val person24 = Person2(age = 4)
}
  1. 次构函数
    Kotlin的主构函数确实给我们带来了很多的方便,在编程开发过程中,能用主构函数,我们优先去用主构函数。其实Kotlin同样允许你像Java一样在类的内部定义构造函数,我们称这样的构造函数为次构函数。

使用次构函数的时候,分两种情况,一种是类不存在主构函数,一种是类存在主构函数。
3.1 不存在主构函数

class Person {
    var name: String = ""
    var age: Int = 18
    constructor(name: String, age: Int) {
        this.name = name
        this.age = age
    }
}

3.2 存在主构函数

class Person(var name: String) {
    var age: Int = 18
    // 因为存在主构函数,所以我们通过“:this(name)”对主构函数成员变量进行赋值
    constructor(name: String, age: Int): this(name) {
        this.age = age
    }
}
注意: 次构函数不能像主构函数那样,通过加上var或者val修饰符,让方法参数变成类的成员属性,次构函数只能接收值
  1. 初始化方法
    第一,调用了主构函数或者次构函数,都会触发初始化方法。
    第二,初始化方法在次构函数之前被执行。
class Person {
    var name: String = ""
    var age: Int = 18
    init {
        println("初始化方法。。。")
    }
    constructor(name: String, age: Int) {
        this.name = name
        this.age = age
        println("次构函数。。。")
    }
}
  1. 嵌套类
    嵌套类分成两种类型,一种是不通过Inner关键字修饰的嵌套类,一种是通过Inner关键字修饰的嵌套类。
    两者的区别主要体现在类的创建以及对外部内属性的访问上。
    5.1 不通过Inner关键字修饰的嵌套类
class Outer {
    val outerValue = 12
    class Inner {
        fun innerFun() {
            // 不能访问外部类的成员属性, outerValue
        }
    }
}

fun main(args: Array<String>) {
    // 在创建的时候,不需要先创建外部类对象
    var inner = Outer.Inner()
    inner.innerFun()
}

5.2 Inner关键字修饰的嵌套类

class Outer {
    val outerValue = 12
    inner class Inner {
        fun innerFun() {
            // 能访问外部类的成员属性
            println("访问外部类的成员属性 $outerValue")
        }
    }
}

fun main(args: Array<String>) {
    // 在创建的时候,需要先创建外部类对象
    var inner = Outer().Inner()
    inner.innerFun()
}
  1. 数据类
    在类定义的时候,通过在最前面加上data关键字,就可以标明这个类是一个数据类。如果一个类被标明为数据类,编译器在编译的时候会自动帮我们覆写常用的一些方法。
    toString方法,方便做日志输出
    hashCode、equals方法,方便对象比较
    copy方法,方便做对象复制
    componentX方法,可以很方面的解析对象包含的属性变量(X是1,2,3 对应属性)
// 没有类体
data class Person(var name: String, var age: Int) 

fun main(args: Array<String>) {
    var person = Person()
    // componentX,全部解析
    val(name, age) = person
    // 第一个属性
    var name2 = person.component1()
}
  1. 枚举类
    枚举类通过enum关键字完成,enum关键字添加在class关键字的前面
enum class Gender {
    MALE, FEMALE, OTHER
}

enum class Week(val date: String, val doSth: String) {
    MON("周一", "work"), 
    TUE("周二", "work"), 
    WED("周三", "work"),
    THU("周四", "work"),  
    FRI("周五", "work"), 
    SAT("周六", "offline"), 
    SUN("周七", "offline")
}

fun test() {
    val sat = Week.SAT
    // sat.name, sat.ordinal, 
    // sat.date, sat.doSth
}
  1. 印章类
    通过enum关键字可以定义一个枚举类,枚举类让一个类拥有了有限多个常量。通过sealed关键字,则可以定义一个印章类,印章类让一个类拥有了有限多个子类。印章类甚至可以理解为一个特殊的枚举类。印章类本身不能被实例化。
sealed class Operation {
    class Add(val num1: Int, val num2: Int): Operation()
    class Subtract(val num1: Int, val num2: Int): Operation()
    class Multiply(val num1: Int, val num2: Int): Operation()
    class Divide(val num1: Int, val num2: Int): Operation()
}

fun operation(op: Operation) {
    when (op) {
        is Operation.Add -> println("add ${op.num1 + op.num2}")
        is Operation.Subtract -> println("subtract ${op.num1 - op.num2}")
        is Operation.Multiply -> println("multiply ${op.num1 * op.num2}")
        is Operation.Divide -> println("divide ${op.num1 / op.num2}")
    }
}

fun main(args: Array<String>) {
    var add = Operation.Add(1, 2)
    operation(add)
}
  1. 类的继承
// 父类需要通过open关键字表示,才可以被继承
open class Person(val name: String) {
    // 父类允许子类重写属性,需要通过open关键字标记。
    open var hairStyle = "有头发"
    // 父类允许子类重写方法,需要通过open关键字标记
    open fun wash(): String {
        return "wash"
    }
}

// Kotlin中的继承关系,通过冒号去表示
// 通过主构给基类赋值
class Man(name: String) : Person(name) {
    // 子类如果重写了父类的属性,需要通过 override标记
    override var hairStyle = "短头发"
    // 子类如果重写了父类的方法,需要通过 override标记
    override fun wash(): String {
        return "man wash"
    }
}

class Woman: Person {
    override var hairStyle = "长头发"
    // 通过次构给基类赋值
    constructor(name: String) : super(name)

    override fun wash(): String {
        return "woman wash"
    }
}
  1. 抽象类
// abstract修饰(不需要open)
abstract class Person(val name: String) {
    // 抽象属性 不能实例化
    // 子类需要将抽象属性初始化,除非子类也是abstract
    abstract var hairStyle: String
    // 抽象方法必须public/protected(默认)
    abstract fun wash(): String
}

class Man(name: String) : Person(name) {
    // 必须override修饰
    override var hairStyle = "短头发"
    // 必须override修饰
    override fun wash(): String {
        return "man wash"
    }
}
  1. 接口
interface Clickable {
    // 抽象属性 不能实例化
    var name: String

    fun click()
    // Java中的接口中的方法,不能有方法体(JDK1.8之后可以有),
    // Kotlin中的接口方法,可以带有方法体(学习了jdk1.8的做法)
    fun printInfo() {
        println("fun from interface...")
    }
}

class Button: Clickable {
    override var name: String = "button"

    override fun click() {
        println("button click...")
    }

    override fun printInfo() {
        println("fun from Button...")
    }
}

实现的多个接口中方法同名的调用:

interface Clickable {
    fun show() {
        println("Clickable#show...")
    }
}

interface Touchable {
    fun show() {
        println("Touchable#show...")
    }
}

class Button: Clickable, Touchable {

    override fun show() {
        // 指定接口,调用方法
        super<Clickable>.show()
        super<Touchable>.show()
        println("button show...")
    }
}
  1. 接口/抽象类的异同
异
1、 接口是定义一些独立的功能、模块、能力,定义为一个一个的接口。比如“可点击的”、“可触摸的”、“可滑动的”、“可吃的”。接口是抽象功能,抽象类是抽象类别。
2、 接口可以看做是抽象类的延申,接口的抽象级别更高
3、 抽象类只能被单继承,接口可以多实现。
4、 抽象类被子类继承,接口被类实现。
5、 方法被abstract修饰,一定是抽象类。(接口也可以用abstract修饰,只是没必要)

同
1、 抽象类和接口都不能被实例化。
2、 抽象类和接口中都可以有方法声明和方法实现。
3、 抽象类和接口中的变量都不能初始化。
4、 子类没有实现完抽象类中的抽象方法,接口实现类没有实现完接口没有方法体的接口方法,都将变为抽象类。
5、 接口中、抽象类中的方法,都不能是私有(private)的。

参考:
Kotlin精讲-黑马程序员(原创)

相关文章

  • 从零开始学Kotlin-类的继承(6)

    从零开始学Kotlin基础篇系列文章 Kotlin中的超类Any Kotlin 中所有类都继承超类 Any 类 A...

  • Kotlin学习之基础数据类型

    Kotlin学习之基础数据类型 @(Kotlin学习) Kotlin的基础数据类型包括数字类型、字符类型、字符串类...

  • Kotlin基础(类)

    适合有java基础的,获取kotlin基础知识/语法等,Kotlin精讲-黑马程序员(原创)的学习笔记。 类 Ko...

  • kotlin基础-类

    一、类组成 1.主构造函数 参数类型写法的三种情况: 2.次构造函数 次构造函数需要委托给主构造函数(直接委托或者...

  • Kotlin修仙之旅:函数,Lambda表达式,常量,变量

    上一篇文章主要总结了一些Kotlin的基础知识,包括类,对象,数组,区间等(Kotlin基础知识(二)类,对象,数...

  • kotlin基础

    kotlin基础 这次的内容主要是kotlin的基本要素:变量、函数、类。同时学习kotlin的控制语句,if、w...

  • Kotlin基础知识总结 函数二

    在上一篇Kotlin基础的介绍之后,我们继续看看kotlin在函数定义,以及Kotlin类的简单实现。 Kotli...

  • Kotlin学习笔记三 (类相关语法)

    Kotlin类的基础知识 访问修饰符 internal是Kotlin特有的 伴生对象 companion obj...

  • Kotlin第三章小结

    Kotlin没有定义自己的集合类,而是在Java集合类的基础上提供了更丰富的api Kotlin可以给函数参数定义...

  • Kotlin基础---枚举类

    Java的枚举 Kotlin的枚举 枚举是极少数Kotlin声明比Java使用了更多的关键字的例子Kotlin用了...

网友评论

      本文标题:Kotlin基础(类)

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