IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> kotlin - object关键字的使用 -> 正文阅读

[移动开发]kotlin - object关键字的使用

kotlin - object关键字的使用

kotlin中的object关键字主要有如下三种用途:

  • 对象表达式
  • 对象声明
  • 伴生对象

对象表达式

对象表达式是完全取代java的匿名内部类的,并且它可以指定多个父类型,和java的匿名内部类还是有区别的,java的匿名内部类只能实现一个父类型。
对象表达式的语法如下:

object:[0-N接口或类]{//后面接口和类不是必须的可以不写
    //对象表达式的类体部分
}

使用示例代码如下:

interface OnClickListener {
    fun onclick()
}

abstract class View {
    abstract fun draw()
}

fun main(args: Array<String>) {
    val view = object : View(), OnClickListener {
        override fun onclick() {
            println("点击了----")
        }

        override fun draw() {
            println("绘制")
        }
    }
    view.onclick()
    view.draw()
}

上面的程序反编译后java生成代码如下:

public final class ObjectDemoKt {
   public static final void main(@NotNull String[] args) {
      <undefinedtype> view = new OnClickListener() {
        ...
      };
      view.onclick();
      view.draw();
   }
}

从反编译后的生成的java代码可以看出,程序在遇到对象表达式的时候就会立即创建对象。
对象表达式有以下规则:

  • 对象表达式不能是抽象类,因为系统在创建对象表达式时会立即创建对象。
  • 对象表达式不能有构造方法。但可以有初始化块。
  • 对象表达式可以包含内部类(被inner修饰的类),但不能包含嵌套类。
    示例代码如下:
fun main(args: Array<String>) {
    var obj = object {//1
        //初始化块
        init {
            println("初始化块")
        }
        //属性
        var name = "kotlin"
        //方法
        fun test() {
            println("test方法")
        }
        inner class Empty
//        class Foo//编译器会报错
    }
    println(obj.name)
    obj.test()
}

上面的代码注释1处可以看出对象表达式没有指定父类型,这就是对象表达式的增强之处。对象表达式的本质其实就是增强版的匿名内部类。

kotlin中的对象表达式可以分为两种情况:

  • 在方法或者函数的局部范围内,或使用private修饰的对象表达式,kotlin编译器可以识别它真实的类型,比如上面的程序。
  • 非private修饰的对象表达式,编译器只会认为它是对父类或接口的处理。如果没有父类或接口系统认为它是Any类型。
    示例代码如下:
class ObjectTypeDemo{

    private val obj1 = object{
        val name:String="fefefe"
    }
    internal val obj2 = object {
        val name:String="fefefe"
    }
    private fun privateObj()=object {
        val name:String="fefefe"
    }
    fun publicObj()=object {
        val name:String="fefefe"
    }
    fun test(){
        //正确,可以识别它的真实类型
        println(obj1.name)
        //错误,不能识别它的真实类型
        println(obj2.name)
        //正确,可以识别它的真实类型
        println(privateObj().name)
        //错误,不能识别它的真实类型
        println(publicObj().name)
    }
}
fun main(args: Array<String>) {
  ObjectTypeDemo().test()
}

对象表达式和java的匿名内部类还有一点区别是,对象表达式可以访问和修改其他作用域的局部变量。而java中匿名内部类要访问其他作用域的变量,这个变量必须是final的。
示例程序如下:

fun main(args: Array<String>) {
    var a:Int=0
    val obj3 = object {
        fun chang(){
            a++
            println("a = $a")
        }
    }
    obj3.chang()
}

对象表达式比java的匿名内部类增强了以下三个方面:

  • 对象表达式可以指定多个父类型
  • kotlin编译器能更准确的识别局部范围内或private对象表达式的类型
  • 对象表达式可以访问和修改其所在范围内的局部变量。

对象声明

对象声明的语法格式如下:

object ObjectName:类型1,类型2,...,类型N{
    //对象声明的类体部分
}

示例代码如下:

object ObjectDeclaration{
    val name:String="declaration"
    fun test(){
        println("test方法")
    }
    class fefe{
        
    }
}

反编译后对象的java代码:

....
private ObjectDeclaration() {
}
static {
   ObjectDeclaration var0 = new ObjectDeclaration();
   INSTANCE = var0;
   name = "declaration";
}
.......

从上面的java代码可以看出kotlin的对象声明的本质就是在静态代码块中创建一个本类对象的实例。在使用的时候其实都是通过实例调用的,同时这也是一种单例模式,在类初始化的时候就会创建一个实例。在使用的时候可以通过类名.成员来访问

对象表达式与对象声明的区别:

  • 对象表达式可以赋值给变量,对象声明不可以。
  • 对象表达式可以包含内部类,不可以包含嵌套类,而对象声明可以包含嵌套类但不能包含内部类。
  • 对象表达式可以定义在方法或函数中,对象声明不可以。

伴生对象和静态成员

在类中定义的对象声明,可以用companion修饰,是它成为伴生对象。
kotlin中的伴生对象的主要目的就是解决kotlin取消了static关键字的问题。
示例代码如下:

class MyClass{
    companion object{
        val name :String="伴生对象"
        fun test(){
            println("test方法")
        }
    }
}
//使用
fun main(args: Array<String>) {
    println(MyClass.name)
    MyClass.test()
    println(MyClass.Companion)//1
}

由于我们是通过类名.成员的方式来访问伴生对象的成员的,所以伴生对象的名称也没什么意义,可以省略。如果我们要访问伴生对象可以通过注释1处的代码来访问。
伴生对象主要作用是为它所在的类模拟静态成员,但只是模拟,实际上伴生对象的成员还是属于伴生对象,并不属于它所在的外部类。
反编译以上代码所对应的java代码如下:

public final class MyClass {
   @NotNull
   private static final String name = "伴生对象";
   @NotNull
   public static final MyClass.Companion Companion = new MyClass.Companion((DefaultConstructorMarker)null);
    ...
   public static final class Companion {
      @NotNull
      public final String getName() {
         return MyClass.name;
      }

      public final void test() {
         String var1 = "test方法";
         boolean var2 = false;
         System.out.println(var1);
      }

      private Companion() {
      }
      ...
   }
}

从上面的java代码可以看出确实伴生对象的成员并不是静态的也不属于Myclass的成员。
要想把伴生对象的成员为其所在的外部类生成对象的静态成员,可以使用@JvmStatic这个注解来实现。代码如下:

class MyClass{
    companion object{
        @JvmStatic
        val name :String="伴生对象"
        @JvmStatic
        fun test(){
            println("test方法")
        }
    }
}

反编译以后java代码如下:

public final class MyClass {
   @NotNull
   private static final String name = "伴生对象";
   @NotNull
   public static final MyClass.Companion Companion = new MyClass.Companion((DefaultConstructorMarker)null);

   @NotNull
   public static final String getName() {
      MyClass.Companion var10000 = Companion;
      return name;
   }

   @JvmStatic
   public static final void test() {
      Companion.test();
   }
   ....
}

可以看出确实是在外部类下生成了对应的静态成员。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-11-09 19:40:29  更:2021-11-09 19:41:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:08:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码