前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >About Kotlin-Kotlin中的类2About Kotlin(2)

About Kotlin-Kotlin中的类2About Kotlin(2)

作者头像
deep_sadness
发布2018-08-30 11:00:15
2.6K0
发布2018-08-30 11:00:15
举报
文章被收录于专栏:Flutter入门

About Kotlin(2)

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

Kotlin中的类

抽象类和接口

抽象类

跟Java一样,使用abstract关键字

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

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

密封类

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

代码语言:javascript
复制
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标记才能够访问外部类的变量

代码语言:javascript
复制
class Outer{
  private val bar:Int = 1
  inner class Inner{
    fun foo()=bar
  }
}
//调用的方式.和java类的内部类调用的方式相同
val demo = Outer().Inner().foo()
嵌套类

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

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

枚举类

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

代码语言:javascript
复制
enum class Direction{
  NORTH,SOUTH,WEST,EAST
}
//和Java一样,每个枚举类都是枚举的实例,可以被初始化
enum class Color(val rgb:Int){
  RED(0xFF0000),
  GREEN(0x00FF00),
  BLUE(0x0000FF)
}
匿名类
代码语言:javascript
复制
enum class ProtocolState{
  WAITING{
    override fun signal()=WAITING
  },
  TALKING{
    override fun signal()=TALKING
  };//这里需要用分号分割
  abstract fun signal():ProtocolState
}

Object类(及匿名类)

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

对象表达式(匿名类)

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

代码语言:javascript
复制
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)
}

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

代码语言:javascript
复制
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关键字声明的一种类。这种类是单例,并且所有的成员都是静态方法。

代码语言:javascript
复制
object DataProviderManager{
  fun registerDataProvider(provider:DataProvider){}
}
伴生对象

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

代码语言:javascript
复制
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 注解,才能将伴生对象的成员生成为真正的静态方法和字段。否则,都只是实例变量

代码语言:javascript
复制
//即使伴生对象的成员看起来像其他语言的静态成员,在运行时他们仍然是真实对象的实例成员,而且,例如还可以实现接口:
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中的属性。方法。修饰符。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.08.18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • About Kotlin(2)
    • Kotlin中的类
      • 抽象类和接口
      • 密封类
      • 内部类
      • 枚举类
      • Object类(及匿名类)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档