Kotlin学习之路--面向对象

面向对象

我们都知道Java是面向对象语言,Kotlin同样是面向对象语言,面向对象有三大特性五大原则,先复习一下什么是面向对象的三大特性:

  • 封装(Encapsulation)

封装,就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

封装的优点:

1. 良好的封装能够减少耦合。

2. 类内部的结构可以自由修改。

3. 可以对成员变量进行更精确的控制。

4. 隐藏信息,实现细节。
  • 继承

继承,指可以让某个类型的对象获得另一个类型的对象的属性的方法。

继承的特性

1. 子类:

通过继承创建的新类,也叫“派生类”;

子类可以拥有自己的属性和方法,即子类可以对父类进行扩展;

子类拥有父类非private的属性,方法;

子类可以用自己的方式实现父类的方法。


2. 父类:被继承的类,也叫“超类”、“基类”

继承概念的实现方式有二类:实现继承与接口继承。

实现继承:是指直接使用基类的属性和方法而无需额外编码的能力,实现继承只支持单继承;

接口继承:是指仅使用属性和方法的名称、但是子类必须提供实现的能力,接口继承支持多继承。
  • 多态

多态,是指一个类实例的相同方法在不同情形有不同表现形式。

多态的优点

1. 消除类型之间的耦合关系
2. 可替换性
3. 可扩充性
4. 接口性
5. 灵活性
6. 简化性

多态存在的三个必要条件

1. 继承
2. 重写
3. 父类引用指向子类对象

Kotlin面向对象使用

  • 类的定义

    1. 无参类的定义
class EmptyClass

fun main(args:Array<String>){
    var ec = EmptyClass() //kotlin创建对象不需要new
    println(ec.toString())//调用类的toString()方法
    println(ec::class) //::表示将class方法传入一个方法中当参数
    println(ec is EmptyClass)//判断类的归属
}

输出结果:

EmptyClass@27c170f0
class EmptyClass
true

image

  1. 带参类的定义
class Student{
    var name:String
    var score:Int = 60 //Int类型必须有初始化值
    var cls:Int = 3

    constructor(name: String, score: Int, cls: Int){
        this.name = name
        this.score = score
        this.cls = cls
    }

    override fun toString(): String {
        return "Student(name='$name', score=$score, cls=$cls)"
    }

}

fun main(args:Array<String>){
    var student = Student("name",32,34)
    println(student.toString())
}

结果输出:
Student(name='name', score=32, cls=34)

image

我们也可以在声明类的同时声明构造函数:

class Teacher(name:String,age:Int){
    var mName = name;
    var mAge = age;
    override fun toString(): String {
        return "name = ${mName} and age = ${mAge}"
    }
}

fun main(args:Array<String>){
    var teacher = Teacher("ailian",32)
    println(teacher.toString())
}

还有一种办法可以不创建属性mName/mAge,而是在构造参数前添加var

class Teacher(var name:String, var age:Int){
    override fun toString(): String {
        return "name = ${name} and age = ${age}"
    }
}

fun main(args:Array<String>){

    var teacher = Teacher("ailian",32)
    println(teacher.toString())
}

以上两种方式输出结果一样:
name = ailian and age = 32

我们也可以IDEA工具自带的方法生成各种构造函数:

image

Kotlin类的继承

Kotlin使用:表示继承关系,比如:


abstract class Animal{//定义一个抽象类
    abstract var name:String//抽象类的属性必须是抽象的
    abstract var age:Int
    abstract fun cry():Boolean//定义抽象方法


    /**
     * 定义一个普通方法、Unit表示无需返回值
     * 默认是final,不可以覆写
     */
    fun smile():Unit{
        "haha..."
    }

    /**
     * 定义一个可以覆写的普通方法
     */
    open fun call():Unit{
        "haha..."
    }
}

class Dog(override var name: String, override var age: Int):Animal(){//override:覆写属性,Cat继承Animal,并实现抽象方法
    override fun cry(): Boolean { //实现方法
        println("${name} is cry...")
        return true
    }

    override fun call() {
        super.call()
        println("${name} is call...")
    }
}

class Pig: Animal() {
    override var name: String = ""
    override var age: Int = 0
    override fun cry(): Boolean {
        println("${name} is cry... age is ${age}")
        return true
    }

}

fun main(args:Array<String>):Unit{
    var pig = Pig()
    pig.name = "Peppa"
    pig.age = 4
    println(pig.cry())

    var dog = Dog("dahuang",3)
    println(dog.call())
    println(dog.cry())
}

结果输出:

Peppa is cry... age is 4
true
dahuang is call...
kotlin.Unit
dahuang is cry...
true

Kotlin接口

  1. Kotlin和Java一样,不支持同时继承多个父类,也就是说继承只能存在一个父类。但是一个类可以同时实现多个接口。

  2. Kotlin的接口和Java只能有抽象方法不同,Kotlin的接口可以有抽象的方法和实现的方法:

  3. 接口没有构造函数,接口的实现和继承一样使用冒号: 实现多个接口用,逗号隔开:

/**
 * 定义一个Animal接口
 */
interface Animal {
    var name: String
    var age: Int
    fun cry()
    fun smile() {
        println("I am smile ... ")
    }
}

/**
 * 定义一个Action接口
 */
interface Action {

}

/**
 * 创建一个Pig类并实现Animal和Action接口
 */
class Pig(override var name: String, override var age: Int) : Animal,Action{
    override fun cry() {
        println("${name} is cry ... ")
    }

}

/**
 * 用另一种形式创建一个类Dog并实现Animal和Action接口
 */
class Dog:Animal,Action{
    override var name: String =""
    override var age: Int = 0
    override fun cry() {
        println("${name} is cry ... ")
    }
}

fun main(args:Array<String>):Unit{
    var pig = Pig("Peppa",2)
    println(pig.cry())

    var dog = Dog()
    dog.name = "xiaowang"
    dog.age = 3
    println(dog.cry())
}

结果输出:

Peppa is cry ... 
kotlin.Unit
xiaowang is cry ... 
kotlin.Unit

Kotlin内部类的使用

内部类就是在类中创建类,Kotlin中可以无限嵌套内部类

内部类分为:普通内部类、匿名内部类

class InnerClass{
    class InnerClass1{
        var name:String = "inner1"
        class InnerClass2{
            var age:Int = 0
            fun innerfun2(){
                /**
                 * 这里不能直接使用InnerClass1的成员变量name,需要通过创建InnerClass1引用后调用
                 */
                println("InnerClass name = ${InnerClass.InnerClass1().name}")
            }
            class InnerClass3{
                fun innerfun3(){

                    /**
                     * //创建最终需要使用方法的对象
                     */
                    InnerClass.InnerClass1.InnerClass2().innerfun2();
                }
            }

            /**
             * 使用inner class 可以直接使用外部类InnerClass2的成员变量
             * 这里并不能引用InnerClass1的name属性,应为InnerClass2未使用inner修饰
             */
            inner class InnerClass4{
                fun innerfun4(){
                    age = 3
                    println("InnerClass4 = ${age}")
                }
            }

            fun run(){
                Thread(object :Runnable {
                    override fun run(){
                        println("i am a anonymous class")
                }
                }).start()
            }
        }
    }
}

fun main(args:Array<String>){
    InnerClass.InnerClass1.InnerClass2().innerfun2()
    InnerClass.InnerClass1.InnerClass2.InnerClass3().innerfun3()//
    InnerClass.InnerClass1.InnerClass2().run()

    /**
     * 注意对比改调用方法与上面三种调用方法的区别
     */
    InnerClass.InnerClass1.InnerClass2().InnerClass4().innerfun4()//
}

结果输出:

InnerClass name = inner1
InnerClass4 = inner1
i am a anonymous class
InnerClass1 = 3

Kotlin中的单列模式

Kotlin中没有静态属性和方法,可以使用关键字 object 声明一个object 单例对象:

object SingleClass{
    var name:String = "single"
    var age:Int = 18
    fun hello(){
        println("Hello World ... ")
    }
}

class CompanionClass {
    /**
     * 通过 companion object 定义一个伴生对象,可以直接使用Class.fun直接调用
     * 一个类只能有一个伴生对象
     */
    companion object CompanionClass1 {
        fun compan() {
            println("I am companion object ...")
        }
        fun compan2(){
            println("I am companion2 object ...")
        }
    }
}


fun main(args:Array<String>){
    println("name = ${SingleClass.name} and age = ${SingleClass.age}")
    SingleClass.hello()
    /**
     * 伴生类的调用
     */
    CompanionClass.compan()
    CompanionClass.compan2()
}

结果输出:

name = single and age = 18
Hello World ... 
I am companion object ...

上一篇:Kotlin学习之路–基础篇
下一篇:Kotlin学习之路–Sealed class类详解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值