美文网首页
Kotlin基础(二)——面向对象

Kotlin基础(二)——面向对象

作者: 紫依卓兰 | 来源:发表于2018-11-12 17:13 被阅读15次

抽象类和接口

接口

  • 直观理解就是一种约定,Kotlin的接口与Objective-c的Proticol比较类似
  • 不能有状态
  • 必须由类对其进行实现后使用

抽象类

  • 实现了一部分协议的半成品
  • 可以有状态,可以有方法实现
  • 必须有子类集成后使用

抽象类和接口的共性

  • 比较抽象,不能直接示例化
  • 有需要子类(实现类)实现的方法
  • 父类(接口)变量可以接受子类(实现类)的示例赋值

抽象类和接口的区别

  • 抽象类有状态,接口没有状态
  • 抽象类有方法实现,接口只能有无状态的默认实现
  • 抽象类只能单继承,接口I可以多实现
  • 抽象类反映本质,接口体现能力

继承(实现)语法要点

  • 父类需要open才可以被继承(抽象类不需要,生来就是被继承的)
  • 父类方法、属性需要open才可以被复写
  • 接口、接口方法、抽象类默认为open
  • 覆写父类(接口)成员需要override关键字
  • class D:A(),B,C
  • 注意继承类时实际上是调用了父类构造方法
  • 类只能但继承,接口可以多实现

接口代理

  • 接口方法实现交给代理类实现
interface Driver{
    fun drive()
    fun abc()
}

class Manager(driver:Driver):Driver by driver


class Manager(driver: Driver):Driver{
    override fun drive(){
        driver.drive()
    }
    override fun abc(){
        driver.abc()
    }
}

接口方法冲突

  • 接口方法可以有默认实现
  • 签名一致且返回值相同的冲突
  • 子类(实现类)必须覆写冲突方法
  • super<父类(接口)名>.方法名(参数列表)

类成员的可见性对比

Kotlin Java
private private
protected protected
- default(包内可见)
internal(模块内可见) -
public public

object

  • 只有一个实例的类
  • 不能自定义构造方法
  • 可以实现接口、继承父类
  • 本质上就是java中最简单的单例

伴生对象与静态方法

  • 每个类可以对应一个半生对象
  • 半生对象的成员全局独一份(针对类来说的)
  • 半生对象的成员类似java的静态成员

伴生对象与静态成员

  • 静态成员考虑用包级函数、变量代替(不依赖于某一个类)
  • Java中要调用Kotlin的伴生对象的方法,在Kotlin代码中添加@JvmStatic注解方便调用,调用成员,添加@JvmField
//Kotlin代码
package printlin.net

/**
 * @created  2018/11/2 12:06
 * @description:
 * @author sunxiaxia
 */
fun main(args: Array<String>) {
    val a = minOf(args[0].toInt(), args[1].toInt())
    val latitude2 = Latitude.ofDouble(5.0)
    val latitude = Latitude.ofLatitude(latitude2)
    println(latitude.TAG)
}

class Latitude private constructor(val value: Double) {
    companion object {
        fun ofDouble(double: Double): Latitude {
            return Latitude(double)
        }

        @JvmStatic
        fun ofLatitude(latitude: Latitude): Latitude {
            return Latitude(latitude.value)
        }
    }
    @JvmField
    val TAG:String = "Latitude"

}

//Java代码
public class JavaStatic {
    public static void main(String...args){
        Latitude latitude = Latitude.Companion.ofDouble(6.0);
        Latitude latitude1 = Latitude.ofLatitude(latitude);
        System.out.println(latitude1.TAG);
    }
}

方法重载和默认参数

- 方法重载(Overloads)

  • 名称相同、参数不同的方法
  • Jvm函数签名的概念:函数名、参数列表,跟返回值无关

默认函数

  • 为函数参数设定一个默认函数
  • 可以为任意位置参数设置默认值
  • 函数调用产生混淆时用具名参数

方法重载与默认参数

  • 二者的相关性以及@JvmOverloads
  • 避免定义关系不大的重载
  • 不好的设计
//java中
List.remove(int)
List.remove(Object)
//在Kotlin中
List.removeAt()=>List.remove(Int)
List.remove(Object)=>List.remove(Object)

扩展成员

  • 为现有类添加方法,属性
fun X.y():Z{...}
val X.m //注意扩展属性不能初始化,类似接口属性
  • java调用扩展成员类似调用静态方法:对应的Kotlin类名Kt.方法名
fun main(args: Array<String>) {
    println("hello".multiply(3))
}
fun String.multiply(int:Int):String{
    val stringBuilder  = StringBuilder()
    for (i in 0 until int){
        stringBuilder.append(this)
    }
    return stringBuilder.toString()
}
//Java中调用
  ExtendsKt.times("kjhfj",7);

属性代理

//定义方法

val/var name:Type by expression
  • 代理者需要实现相应的setValue/getValue方法
  • lazy原理剖析

数据类(Data clas,再见JavaBean)

  • 默认实现的copy、toString等方法
  • componentN方法 ,可以自己写
val (a,b,c) = dataClass实例
例:
val person = Person("张丹",35)
    val (a,b) = person
    println("姓名:$a,年龄:$b")
  • allOpen和noArg插件,解决数据类被final修饰且没有空的构造函数的问题(dataClass是final,从设计角度上不允许有子类,通过allopen插件可是实现在编译期通过字节码的方式将fianl去掉,通过noArg插件可以实现无参构造方法)

group 'cn.onestravel'
version '1.0-SNAPSHOT'



buildscript {
    ext.kotlin_version="1.3.0"
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version"
    }
}

apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'kotlin-allopen'
apply plugin: 'kotlin-noarg'

noArg{
    annotation("net.println.demo1.DataBean")
}

allOpen{
    annotation("net.println.demo1.DataBean")
}

repositories {
    mavenCentral()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"

}

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

内部类

  • 定义在类内部的类,默认是静态内部类(java默认的是非静态内部类),非静态用inner关键字,与类成员有相似的访问控制
  • 内部类访问外部类的成员用@this@Outter,内部类的成员可以用this@Inner也可以不用。

匿名内部类

  • 没有定义名字的内部类
  • 类名编译时生成,类似Outter@1.class
  • 可以继承父类、实现多个接口(Java不能同时继承父类又实现接口,要么继承一个类,要么实现一个接口)

枚举(enmu)

  • 实例可数的类,注意枚举也是类
  • 可以修改构造,添加成员
  • 可以提升代码的表现力,也有一定的性能开销

密封类(sealed)

  • 子类可数(枚举是实例可数)
  • Kotlin v1.1之前子类必须定义在密封类的内部类
  • v1.1后,子类只需要与密封类在同一个文件中

相关文章

  • Kotlin基础(二)——面向对象

    抽象类和接口 接口 直观理解就是一种约定,Kotlin的接口与Objective-c的Proticol比较类似 不...

  • 第一天

    概述: Kotlin基础面向过程面向对象接口、扩展、泛型 为什么学习Kotlin 1.Google官方指定2.简介...

  • java SE目录

    java SE目录 java基础(一)java基础(二)关键字面向对象(一)面向对象(二)面向对象(三)集合(一)...

  • 第六篇:Kotlin之面向对象简单

    上篇:Kotlin之函数Lambda表达式 下篇:Kotlin之面向对象升级(一) Kotlin也支持面向对象的三...

  • kot

    #Kotlin之班门弄斧 ##面向对象 ##java和kotlin的交互 ##协程及协程框架 ## 面向对象 ...

  • 第七篇:Kotlin之面向对象升级(一)

    上篇:Kotlin之面向对象简单 本章节来介绍Kotlin面向对象的高级部分: 一. 扩展:kotlin的扩展是一...

  • (二)Kotlin 面向对象

    一、面向对象的概念 本质上就是解决如何用程序描述世界的问题 讨论如何把实际存在的东西映射成程序的类和对象 一种程序...

  • Kotlin(二)面向对象

    面向对象 2.1 kotlin中的类 不可变属性成员。用val声明不可见成员,底层是java 的final实现2...

  • kotlin 基础 10 面向对象

    定义第一个类 定义类有点像函数,对了在 kotlin 中函数是一等公民的原因吧,这里定义类可以传入属性。 静态和动...

  • Kotlin-面向对象-基础

    方法 Kotlin 中方法和函数其实是统一的,但是我们这么理解区别:函数:直接定义在文件中的 fun。方法:定义在...

网友评论

      本文标题:Kotlin基础(二)——面向对象

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