在Java中,我们要对一个类进行扩展方法,可以采用继承该类新增方法。
Anim原有run方法:
class Anim {
protected String name;
Anim(String name) {
this.name = name;
}
protected void run() {
System.out.println("跑");
}
}
Dog继承Anim类扩展eat方法:
class Dog extends Anim {
Dog(String name) {
super(name);
}
/**
* 扩展eat函数
*/
protected void eat() {
System.out.println("吃东西");
}
}
dog就扩展了eat方法:
var dog = Dog("旺财")
dog.run()
dog.eat()
在Kotlin中,我们可以使用扩展函数来新增方法
fun 被扩展类名.扩展函数名( 参数 ) {
//实现代码
}
那么,给Anim加一个扩展方法:
fun Anim.eat(food: String) {
println("吃$food")
}
Dog类继承Anim,继承了扩展函数eat(food: String),dog调用eat,打印“吃饭”
var dog = Dog("旺财")
dog.eat("饭")
在java中调kotlin扩展函数:Extends为扩展函数文件名,
ExtendsKt.eat(Dog(), "饭");
如果扩展函数和被扩展类中的成员函数有相同的接收类型、名字和参数,那么这种情况下总是取成员函数。
class Dog {
fun showName(){
print("Dog")
}
}
fun Dog.showName(){
print("Cat")
}
fun main(args: Array<String>) {
Dog().showName()
}
如果我们调用 Dog 类的 showName(),它将输出“Dog”,而不是“Cat”。
扩展函数原理
对如下这个扩展函数进行反编译:
fun String.first(num: Int): String {
return this.substring(0, num)
}
翻译成的代码:
public static final String first(@NotNull String $this$first, int num) {
Intrinsics.checkNotNullParameter($this$first, "$this$first");
byte var3 = 0;
boolean var4 = false;
String var10000 = $this$first.substring(var3, num);
Intrinsics.checkNotNullExpressionValue(var10000, "(this as java.lang.Strin…ing(startIndex, endIndex)");
return var10000;
}
编译器会生成一个函数,传入当前扩展类对象作为第一个参数,在函数中对该对象进行一些列处理。
在项目中实际使用
在项目中,我们通常使用扩展函数用来代替Java中的Utils类。比如给Activity、TextView、ImageView、File、Context等类加扩展函数,以达到写工具类的同等效果。
屏幕尺寸转化扩展函数:
fun Context.dp2px(dpValue: Float): Int {
val scale = resources.displayMetrics.density
return (dpValue * scale + 0.5f).toInt()
}
fun Context.px2dp(pxValue: Float): Int {
val scale = resources.displayMetrics.density
return (pxValue / scale + 0.5f).toInt()
}
fun Context.sp2px(spValue: Float): Int {
val scale = resources.displayMetrics.scaledDensity
return (spValue * scale + 0.5f).toInt()
}
fun Context.px2sp(pxValue: Float): Int {
val scale = resources.displayMetrics.scaledDensity
return (pxValue / scale + 0.5f).toInt()
}
Activity显示隐藏软键盘扩展函数:
/**
* 显示软键盘
*/
fun Activity.showKeyboard() {
var imm: InputMethodManager = this.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
?: return
var view = this.currentFocus
if (view == null) {
view = View(this)
view!!.isFocusable = true
view!!.isFocusableInTouchMode = true
view!!.requestFocus()
}
imm.showSoftInput(view, InputMethodManager.SHOW_FORCED)
}
/**
* 隐藏软键盘
*/
fun Activity.hideKeyboard() {
var imm: InputMethodManager = this.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
?: return
var view = this.currentFocus
if (view == null) {
view = View(this)
}
imm.hideSoftInputFromWindow(view.windowToken, 0)
}
文件操作扩展函数:
/**
* 存储bitmap到本地
* @param bitmap
* @param file
* @return
*/
fun Bitmap.bitmapToFile(file: File): Boolean {
try {
if (!file.exists()) {
if (file.parentFile.exists()) file.createNewFile()
}
val out = FileOutputStream(file)
compress(Bitmap.CompressFormat.PNG, 100, out)
out.flush()
out.close()
return true
} catch (e: FileNotFoundException) {
e.printStackTrace()
} catch (e: IOException) {
e.printStackTrace()
}
return false
}
/**
* 创建文件夹
*
* @param path
* @return
*/
fun String.mkDirs(): File {
val file = File(this)
if (!file.exists()) {
file.mkdirs()
}
return file
}
网友评论