About Kotlin-Kotlin中的类2

About Kotlin(2)

继续昨天的部分。介绍Kotlin中的类。

Kotlin中的类

抽象类和接口

抽象类

跟Java一样,使用abstract关键字

open class Base{
  open fun f(){}
}
abstract class Derived:Base(){
  override abstract fun f()
}
接口
//内部可以直接写实现
interface MyInterface{
  fun bar()
  fun foo(){    //默认实现
    println("foo")
  }
}

//接口中可以写属性。不允许初始化。实现类必须初始化
interface MyInterface2{
  var name:String //抽象
}
class MyImpl:MyInterface2{
  override var name:String="override name" //重载属性
}

密封类

使用sealed修饰符修饰。其实是一组类的集合。可以用来表示受限的类的继承结构。
其也可以有子类,所有子类也必须在相同的文件中声明。
密封类从某种意义上说,它们是枚举类的扩展:枚举类型的值集也受到限制,但每个枚举常量仅作为单个实例存在,而密封类的子类可以包含多个实例并包含状态。这样又具备了枚举不具备的灵活性。

sealed class BaseClass {

    class Test1 : BaseClass() {
        override fun test() {
            println("Test1实例")
        }

    }
    class Test2 : BaseClass() {
        override fun test() {
            println("Test2实例")
        }
    }
    object Test3 : BaseClass() {
        override fun test() {
            println("Test3实例")
        }
    }
    open fun test() {
        println("BaseClass实例")
    }
}

fun test(instance: BaseClass)=when(instance){
    is BaseClass.Test1-> instance.test()
    is BaseClass.Test2-> instance.test()
    is BaseClass.Test3->instance.test()
}

fun main(str: Array<String>) {
    test( BaseClass.Test1() )
    test( BaseClass.Test2() )
    test( BaseClass.Test3 )
}

内部类

inner标记

使用inner标记才能够访问外部类的变量

class Outer{
  private val bar:Int = 1
  inner class Inner{
    fun foo()=bar
  }
}
//调用的方式.和java类的内部类调用的方式相同
val demo = Outer().Inner().foo()

嵌套类

不用inner标记,直接写在类的内部的类,在kotlin中称为所谓的嵌套类

class Outer{
   private val bar: Int = 1
   class Nested{
     fun foo()=2
   }
}
//嵌套类的调用有点像静态内部类。
val demo = Outer.Nested().foo()

枚举类

枚举类最基本的用法是实现类型安全的枚举

enum class Direction{
  NORTH,SOUTH,WEST,EAST
}
//和Java一样,每个枚举类都是枚举的实例,可以被初始化
enum class Color(val rgb:Int){
  RED(0xFF0000),
  GREEN(0x00FF00),
  BLUE(0x0000FF)
}

匿名类

enum class ProtocolState{
  WAITING{
    override fun signal()=WAITING
  },
  TALKING{
    override fun signal()=TALKING
  };//这里需要用分号分割
  abstract fun signal():ProtocolState
}

Object类(及匿名类)

在Kotlin中使用对象表达式对象声明进行表示

对象表达式(匿名类)

匿名类其实就是在Java中的匿名内部类。
java中调用方法时,提供的匿名内部类

fun countClicks(window:JComponent){
  var clickCount = 0
  val enterCount=0
  
  //通常的情况,使用Object开头就可以
window.addMouseListener(object:MouseAdapter()){
  override fun mouseClicked(e:MouseEvent){
    //与Java不同的是,甚至可以直接访问变量。(未被final修饰)!
    clickCount++
    enterCount++
  }
  ...
}
}

//多个超类的情况
open class A(x:Int){
  public open val y:Int=x
}
interface B{...}
val ab :A=object:A(1),B{
  override val y = 15
}

//如果只是需要一个对象,什么都不需要的话。也可以直接写
fun foo(){
  val adHoc = object{
    var x:Int = 0
    var y:Int =0
  }
  println(adHoc.x+adHoc.y)
}

这里有一点值得特别注意的的是:
匿名对象可以用作只在本地私有作用域中声明的类型。只能做为私有函数的返回值。

class C{
  //私有函数,所以其返回雷士的对象是匿名对象
    private fun foo()=object{
        val x :String="x"
    }
  //默认都是public final的方法.使用对象声明返回的类型是Any
    fun publicFoo()=object{
        val x:String="x"
    }
  
    fun bar(){
        val x1= foo().x //可以直接访问
        val x2= publicFoo().x //错误!未能解析的引用"x"
    }
}

对象声明

单例

是指使用object关键字声明的一种类。这种类是单例,并且所有的成员都是静态方法。

object DataProviderManager{
  fun registerDataProvider(provider:DataProvider){}
}
伴生对象

类内部的对象声明可以使用companion关键字标记

class MyClass{
//就是静态内部类咯?但是每个类的伴生对象只能有一个!?
  companion object Factory{
    fun create():MyClass=MyClass()
  }
}

//调用方式类似于Java中的静态方法
val instance = MyClass.create()

//如果按照下列写法,调用时,可以使用名称 Companion
class MyClass{
  companion object{}
}

val x = MyClass.Companion

这里需要注意的是:

在 JVM 平台,只有使用 @JvmStatic 注解,才能将伴生对象的成员生成为真正的静态方法和字段。否则,都只是实例变量

//即使伴生对象的成员看起来像其他语言的静态成员,在运行时他们仍然是真实对象的实例成员,而且,例如还可以实现接口:
interface Factory<T> {
    fun create(): T
}
class MyClass {
    companion object : Factory<MyClass> {
      //注意需要写Override
        override fun create(): MyClass = MyClass()
    }
}
//当然,在 JVM 平台,如果使用 @JvmStatic 注解,你可以将伴生对象的成员生成为真正的静态方法和字段。
//@JvmStatic 注解也可以应用于对象或伴生对象的属性, 使其 getter 和 setter 方法在该对象或包含该伴生对象的类中是静态成员。更多详细的内容之后再看
class MyClassJVM {
     companion object : Factory<MyClassJVM> {
       @JvmStatic override fun create(): MyClassJVM = MyClassJVM()
    }
}

到这里,就大概把Kotin中的类汇总完了。接下来,也还是会按照参考文章的这个思路。记录Kotlin中的属性。方法。修饰符。

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

推荐阅读更多精彩内容