如何在芬兰湾的科特林中使用扩展函数和扩展属性

  介绍

如何在芬兰湾的科特林中使用扩展函数和扩展属性?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

芬兰湾的科特林能够扩展一个类的新功能而无需继承该类或者使用像装饰者这样的设计模式。这通过叫做扩展的特殊声明完成,例如,你可以为一个你不能修改的,来自第三方库中的类编写一个新的函数。这个新增的函数就像那个原始类本来就有的函数一样,可以用普通的方法调用。这种机制称为扩展函数。

public  class  Utils  {      ,public  static  float  dp2px (int  dpValue), {   return 才能;(0.5 f  +, dpValue  *, Resources.getSystem () .getDisplayMetrics () .density);   ,}   }

在代码中直接调用Utils.dp2px(100)来使用,

val  dp2px =, Utils.dp2px (100)

如果用芬兰湾的科特林扩展函数的方式来实现,会是怎么调用呢?

val  dp2px =, 100. dp2px ()

是不是很惊讶,100作为一个Int,竟然直接调用了一个dp2px方法,如果你去源码里找,找其实是没有个方法的。我们没有动源码,而是使用拓展函数的方式为Int增加了一个方法。

fun  Int.dp2px ():, Float  {   ,return  (0.5 f  +,却;能够*,Resources.getSystem () .displayMetrics.density)   }

<>强扩展函数

我们再来举个吗?,有一个人类如下

class 人(名字:val 字符串),{      ,fun 吃(),{   Log.i才能(名字,“我# 39;m  going 用eat")   ,}      ,fun 睡眠(),{   Log.i才能(名字,“我# 39;m  going 用sleep")   ,}      }

它有两个方法,一个是吃饭,一个是睡眠,调用的话就分别打印相应的日志。我们现在不想动的人类,但是又想给他增加一个新的方法,怎么做呢。我们可以新建一个文件PersonExtensions。kt,再通过一下代码实现,就可以人为类新增一个喝方法啦。

fun  Person.drink (), {   ,Log.i (“Person",,“$ {this.name}:,我# 39;m  going 用drink")   }

声明一个扩展函数,我们需要用一个接收者类型也就是被扩展的类型来作为他的前缀上。面我们就是以人作为一个扩展函数的接收类型,为其拓展来喝方法。我们在其方法中调用了这个,这个这指的就是调用这个拓展方法的当前人对象。

如何在芬兰湾的科特林中使用扩展函数和扩展属性

扩展函数调用的话也和普通的方法相同。但是你会发现IDE显示的方法颜色有点不一样。

如何在芬兰湾的科特林中使用扩展函数和扩展属性

由此也可以看出普通的方法和我们的拓展函数是不同的。下面我们来看看扩展函数的实际实现。

在Android工作室中,我们可以查看芬兰湾的科特林文件的字节码,然后再反编译为Java代码。上面我们为人扩展函数转为Java代码后如下。

@Metadata (   ,mv =, {1,, 1,, 15},   ,bv =, {1,, 0,, 3},=,k  2,   ,d1 =, {“\ u0000 \ f \ n \ u0000 \ n \ u0002 \ u0010 \ u0002 \ n \ u0002 \ u0018 \ u0002 \ n \ u0000 \ u001a \ n \ u0010 \ u0000 \ u001a \ u00020 \ u0001 * \ u00020 \ u0002¨\ u0006 \ u0003"},   ,d2 =, {“cook",,,,,,“Lcom/chaochaowu/kotlinextension/人;“,,“app_debug"}   )   public  final  class  PersonExtensionsKt  {   ,public  static  final  void 库克(@NotNull  Person 这个厨师美元),{   Intrinsics.checkParameterIsNotNull才能(这个厨师,美元,“这cook"美元);   Log.i才能(“Person",,这cook.getName美元(),+,“:,我# 39;m  going 用cook");   ,}   }

妹想到啊,它原来是一个静态的最后一声明的静态方法,它的入参是一个类人型,也就是我们之前的接收类型。那在Java代码中能不呢调用呢?

PersonExtensionsKt.cook (new 人(“Bob"));

竟然也没有报错!由此可见,所谓扩展函数并不是真正的在类中增加了一个方法,而是通过外部文件的静态方法来实现,其实就是和跑龙套类一个道理。

因为将一个人作为入参传入了方法中,所以我们也就可以在方法内对这对个人象进行操作,这也就是在扩展方法中我们可以使用这个来访问人属性的原因。

如何在芬兰湾的科特林中使用扩展函数和扩展属性