Kotlin——面向对象(4)

1、面向对象-抽象类与接口

1)什么是接口
接口,直观理解就是一种约定
kotlin的接口与Objcet-C的Protocal比较类似
举例:

interface InputDevice{
fun input(event:Any)
}

2}接口
a.接口不能有状态
b.必须由类对其进行实现后使用
3)抽象类
a.实现了一部分协议的半成品
b.可以有状态,可以有方法实现
c.必须由子类继承后使用
4)抽象类和接口的共性
a.比较抽象,不能直接实例化
b.有需要子类(实现类)实现的方法
c.父类(接口)变量可以接受子类(实现类)的实例赋值
d.抽象类反映本质,接口体现能力
5)抽象类和接口的区别
a.抽象类有状态,接口没有状态
b.抽象类有方法实现,接口只能有无状态的默认实现
c.抽象类只能单继承,接口可以多实现

2、继承

1)父类需要open才可以被继承
2)父类方法、属性需要open才可以被复写
3)接口、接口方法、抽象类默认为open
4)复写父类(实现接口)的方法需要override关键字
5)class D:A(),B,C
6)继承类时实际上是调用了父类构造方法
7)类只能单继承,接口可以多实现
接口代理

class Leader(val dr:Drive,val pp:PPT):D by dr,P by pp

接口方法实现交给代理类实现
事例:

interface  D{
    fun drive()
}

interface P{
    fun write()
}
 class Drive:D{
   override fun drive(){
        println("开车")
    }
}

class PPT:P{
  override fun write(){
        println("写ppt...")
    }
}

//接口代理
class Leader(val dr:Drive,val pp:PPT):D by dr,P by pp

fun main(args: Array<String>) {
    val lead = Leader(pp=PPT(),dr=Drive())
    //接口代理调用
    lead.drive()
    lead.write()
}

接口方法冲突
1)接口方法可以有默认实现
2)方法名、方法参数以及返回值相同,否则会有冲突
3)子类(实现类)必须复写冲突方法
4)super<[父类(接口)名]>.[方法名]([参数列表])
事例:

open class A {
    open fun x(): Int = 'A'.toInt()
}

interface B {
    fun x(): Int = 'B'.toInt()
}

interface C {
    fun x(): Int = 'C'.toInt()
}

class F(var y: Int) : B, C, A() {
    override fun x(): Int {
        return when {
            y > 0 -> super<A>.x()
            y < 0 -> super<B>.x()
            else -> super<C>.x()
        }
    }
}

fun main(args: Array<String>) {
    println(F(-1).x())//B
    println(F(0).x())//C
    println(F(1).x())//A
}

运行结果:66,67,65

3、类及其成员的可见性(private,protected,internal,public)

注:internal在和java兼容方面依旧存在问题,暂不建议使用


可见性对比.png

4、object

1)只有一个实例的类
2)不能自定义构造方法
3)可以实现接口、继承父类
4)本质上就是单例模式最基本的实现
注:如果不考虑懒加载等因素,Kotlin中写单例,使用的是object。

5、伴生对象与静态成员

1)每个类可以对应一个伴生对象
2)伴生对象的成员全局独一份
3)伴生对象的成员类似Java中的静态成员
4)静态成员考虑用包级函数、变量替代
5)JvmField和JvmStatic的使用
事例:
无论加不加@JvmStatic@JvmField在kotlin都可正常调用,而Java若想调用,则必须添加这两个注解。

class Latitude private constructor(val d:Double){
    companion object {
        @JvmStatic
        fun la(d: Double):Latitude{
            return Latitude(d)
        }
        @JvmStatic
        fun getD(latitude: Latitude):Latitude{
            return Latitude(latitude.d);
        }
        @JvmField
        val TAG = "TAG"
    }
}

kotlin中调用

fun main(args: Array<String>) {
var latitude = Latitude.la(6.66)
val latitude2 = Latitude.getD(latitude)
val tag = Latitude.TAG
}

java中调用

Latitude latitude = Latitude.la(3.234);
Latitude latitude2 = Latitude.getD(latitude);
String tag = Latitude.TAG;

6、方法重载与默认参数

1)方法重载
a.Overloads
b.名称相同、参数不同的方法
c.Jvm函数签名的概念:函数名、参数列表
d.跟返回值无关
2)默认参数
a.为函数参数设定一个默认值
b.可以为任意位置的参数设置默认值
c.函数调用产生混淆时用具名参数
3)方法重载和默认参数
a.二者的相关性以及@JvmOverloads(给java中调用kotin中的默认参数时使用)
事例:

class Overloads {
//    fun a(): Int {
//        return 0
//    }
   //  @JvmOverloads
    fun a(int: Int = 0): Int {
        return int
    }

    fun a(str: String): Int {
        return str.toInt()
    }
}

fun main(args: Array<String>) {
    val ovarLoads = Overloads()
    ovarLoads.a(1)
    ovarLoads.a("2")
//kotlin中调用
    println(ovarLoads.a())
}
未加@JvmOverLoads时javad调用.png

加上@JvmOverLoads时java的调用.png

b.避免定义关系不大的重载
c.不好的设计

List.remove(Int)
List.remove(Object)

事例:


java中remove.png

kotlin中remove.png

7、扩展成员

为现有类添加方法属性

fun X.y():Z{...}
val X.m 注:扩展属性不能初始化,类似接口属性
Java调用扩展成员类似调用静态方法
事例:

二元运算符.png

fun main(args: Array<String>) {
    println("abc".times(6))
    println("a" * 6)
    println("a".a )
    println("b".b)
}

operator fun String.times(num: Int): String {
    val sb = StringBuffer()
    if (num > 0) {
        for (i in 0 until num) {
            sb.append(this)
        }
    }
    return sb.toString()
}

val String.a
    get() = 5
var String.b
    set(value){}
    get() = 6

运行结果:


运行结果.png

8、属性代理

1)定义方法

val/var <property name>:<Type> by <expression>

2)代理者需要实现相应的setValue/getValue方法
事例:

class Delegate {
    val x1 by lazy {
        "Hello X"
    }
    var x2 by X()
    var x3 by X()

}

class X {
    private var value: String? = null

    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        println("getValue---------$thisRef--------------------${property.name}")
        return value ?: ""
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("setValue------------$thisRef----------------${property.name}-----------$value")
        this.value = value
    }
}

fun main(args: Array<String>) {
    val delegate = Delegate()
    println(delegate.x1)
    println(delegate.x2)
    println(delegate.x3)
    delegate.x3 = "666666666666666666666"
    println(delegate.x3)
}

输出结果:


运行结果截图.png

9、数据类(allOpen,noArg插件,再见,javaBean)

1)data class默认实现了copy、toString、hashCode、equals等方法
2)componentN方法
3)allOpen和noArg插件

10、内部类(this@Outter,this@Inner)

内部类
a.定义在类内部的类
b.与类成员有相似的访问控制
c.默认是静态内部类,非静态用inner关键字
d.this@Outter,this@Inner的用法
匿名内部类
a.没有定义名字的内部类
b.类名编译时生成,类似Outter$1.class这样的类名
c.可继承父类、实现多个接口,与Java注意区别

11、枚举(enum)

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

12、密封类(sealed Class)

1)子类可数
kotlin版本<1.1,子类必须定义为封闭类的内部类
v1.1,子类只需要与密封类在同一文件中
2)与枚举类似却又不同

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

推荐阅读更多精彩内容

  • 设计模式概述 在学习面向对象七大设计原则时需要注意以下几点:a) 高内聚、低耦合和单一职能的“冲突”实际上,这两者...
    彦帧阅读 3,710评论 0 14
  • 面向对象笔记 一、 对象在内存中的存放方法以及被调用过程 class文件首先被加载到方法区中的class文件内容区...
    VictorBXv阅读 427评论 0 2
  • java继承 继承的概念 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。 继承就是子类继...
    863cda997e42阅读 630评论 0 1
  • 你还在吗?秋雨骤至的夜晚,你还在吗? 我多想对你说,七月,七月是美好的季节。我们都有大把时间去游山玩水。巫山巫峡气...
    沅有芷兮兮阅读 122评论 0 1
  • 【每日一歌】 你 【每日一得】 1、每个人的痛点都是他的恐惧,恐惧是痛点。人们会...
    采蘑菇的小Timor阅读 78评论 0 1