目录
1、Kotlin中的访问修饰符
2、静态方法
3、object关键字
3.1、对象表达式
3.2、对象声明
4、companion object(伴生对象)
5、静态工具类的实现:
6、单例的实现
1、Kotlin中的访问修饰符
修饰符 | 含义 | 与Java比较 |
---|---|---|
public | Kotlin中的默认修饰符,全局可见 | 与Java中public效果相同 |
protected | 受保护的修饰符,仅类和子类可见 | Java中还有包内可见 |
private | 私有修饰符,类内修饰只有本类可见,类外修饰仅文件可见 | Java中仅类内可见 |
internal | 模块内可见 | 无 |
2、静态方法
在Java中我们经常写这样的工具类,来进行开发。
public class StringUtil {public static boolean isEmpty(String str){return "".equals(str);}
}
那么Kotlin中的静态方法是怎么实现的呢?
首先我们来讲几个关键字。
3、object关键字
object
关键字可以表达两种含义:一种是对象表达式
,另一种是 对象声明
。
3.1、对象表达式
object可以继承一个类,或者实现一个接口。(下面代码View.OnClickListener {} 属于将接口实例化成一个匿名内部类,然后用object来继承。)
val text: TextView = findViewById(R.id.text)//基础表达text.setOnClickListener(View.OnClickListener {})//object 表达匿名内部类对象 (OnClickListener就是一个匿名内部类)val clicListener = object : View.OnClickListener {override fun onClick(v: View?) {}}//lambda简化OnClickListener匿名内部类val clicListener1 = View.OnClickListener {}text.setOnClickListener(clicListener1)
上面代码其实就是我们经常要给 view
设置的点击事件,OnClickListener
事件是一个匿名内部类的对象,用object
来继承。
3.2、对象声明
用object
修饰的类为静态类,里面的方法和变量都为静态
的。
3.2.1 直接声明类
object DemoManager {private val TAG = "DemoManager"fun test() {Log.e(TAG,"此时 object 表示 声明静态内部类")}}
3.2.2 声明静态内部类
类内部的对象声明,没有被inner
修饰的内部类都是静态的
class DemoManager{object MyObject {fun test() {Log.e(TAG,"此时 object 表示 直接声明类")}}
}
4、companion object(伴生对象)
companion object
修饰为伴生对象,伴生对象在类中只能存在一个,且只能写在类里边。
它可以用来实现Java那种静态工具类和单例。
class StringUtils{companion object{fun isEmpty4(str: String): Boolean {return "" == str}@JvmStaticfun isEmpty5(str: String): Boolean {return "" == str}}
}
5、静态工具类的实现:
上面我们知道被object关键字修饰的类,都是静态类,类的内部的方法和变量都是静态方法和变量,这样我们就可以通过类名,来直接调用这些方法了,但是需要注意的是:object修饰的类是静态内部类,它的名字是无法和文件类是一样的,所以他在java 中调用的时候是:(文件名+静态内部类名+方法名)
工具类:StringUtils
//它的文件名是StringUtils,所以OusideUtils是无法和文件名一样的
object OusideUtils {fun isEmpty2(str: String): Boolean {return "" == str}@JvmStaticfun isEmpty3(str: String): Boolean {return "" == str}
}class StringUtils{object InsideUtils {fun isEmpty(str: String): Boolean {return "" == str}@JvmStaticfun isEmpty1(str: String): Boolean {return "" == str}}companion object{fun isEmpty4(str: String): Boolean {return "" == str}@JvmStaticfun isEmpty5(str: String): Boolean {return "" == str}}}
kotlin中调用工具类方法
注意:前面我们讲过被@JvmStatic注解的方法是可以当做静态方法来直接被调用的。但是好想在kotlin中调用的话,注不注解都是一样的效果
1、kotlin中直接调用StringUtils类名外的静态内部类的方法,是可以直接用OusideUtils类名+方法方式调用的,但是这样我们无法很明确的知道它的文件名是哪个。
2、调用StringUtils类名内的静态内部类方法的话,需要用 外部类名+静态内部类名+方法名的形式,会有点繁琐
3、用伴生对象的话,就可以实现直接用 外部类名+方法名的形式来实现调用
class TestMain {fun testStringUtils() {//类名内的静态内部类val isEmpty = StringUtils.InsideUtils.isEmpty("小子")val isEmpty1 = StringUtils.InsideUtils.isEmpty1("")//类名外的静态内部类val isEmpty2 = OusideUtils.isEmpty2("小子2")val isEmpty3 = OusideUtils.isEmpty3("")//伴生对象val isEmpty4 = StringUtils.isEmpty4("小子4")val isEmpty5 = StringUtils.isEmpty5("")println("isEmpty=$isEmpty")println("isEmpty1=$isEmpty1")println("isEmpty2=$isEmpty2")println("isEmpty3=$isEmpty3")println("isEmpty4=$isEmpty4")println("isEmpty5=$isEmpty5")}
}fun main() {val testMain= TestMain()testMain.testStringUtils()
}
Java中调用工具类方法
注意:可以看到当Java调用kotlin的静态工具类的时候,@JvmStatic注解的作用就显示了出来,没被注解的方法都需要调用它们各自的匿名对象来调用各自的方法,被注解的方法,就可以实现用类名+方法名的方式来实现和Java中静态工具类的相同方式。
public class TestJava {public static void main(String[] args) {//调用StringUtils类内部的匿名静态类的方法boolean isEmpty = StringUtils.InsideUtils.INSTANCE.isEmpty("小子");boolean isEmpty1 = StringUtils.InsideUtils.isEmpty1("");//调用StringUtils类外部的匿名静态类的方法boolean isEmpty2 = OusideUtils.INSTANCE.isEmpty2("小子2");boolean isEmpty3 = OusideUtils.isEmpty3("");//调用StringUtils的伴生对象的静态方法boolean isEmpty4 = StringUtils.Companion.isEmpty4("小子4");boolean isEmpty5 = StringUtils.isEmpty5("");System.out. println("isEmpty="+isEmpty);System.out. println("isEmpty1="+isEmpty1);System.out. println("isEmpty2="+isEmpty2);System.out. println("isEmpty3="+isEmpty3);System.out. println("isEmpty4="+isEmpty4);System.out. println("isEmpty5="+isEmpty5);}}
6、单例的实现
方案一:在前面我们讲过,在kotlin中通过object 创建匿名内部类的方式可以实现单例的模式,我们在Java中调用他的内部方法的时候,就可以看到会出现一个INSTANCE 的关键字,其实这个就是这个匿名内部类的单例对象。
public class TestJava {public static void main(String[] args) {//调用StringUtils类内部的匿名静态类的方法boolean isEmpty = StringUtils.InsideUtils.INSTANCE.isEmpty("小子")//调用StringUtils类外部的匿名静态类的方法boolean isEmpty2 = OusideUtils.INSTANCE.isEmpty2("小子2");//调用StringUtils的伴生对象的静态方法boolean isEmpty4 = StringUtils.Companion.isEmpty4("小子4"); }}
方案二:我们这里还有一种比较推荐的单例模式的书写方式
class SingleClass private constructor() {companion object {fun get(): SingleClass {return Holder.instance}}private object Holder {val instance = SingleClass()}
}