目录
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
}
@JvmStatic
fun isEmpty5(str: String): Boolean {
return "" == str
}
}
}
5、静态工具类的实现:
上面我们知道被object关键字修饰的类,都是静态类,类的内部的方法和变量都是静态方法和变量,这样我们就可以通过类名,来直接调用这些方法了,但是需要注意的是:object修饰的类是静态内部类,它的名字是无法和文件类是一样的,所以他在java 中调用的时候是:(文件名+静态内部类名+方法名)
工具类:StringUtils
//它的文件名是StringUtils,所以OusideUtils是无法和文件名一样的
object OusideUtils {
fun isEmpty2(str: String): Boolean {
return "" == str
}
@JvmStatic
fun isEmpty3(str: String): Boolean {
return "" == str
}
}
class StringUtils{
object InsideUtils {
fun isEmpty(str: String): Boolean {
return "" == str
}
@JvmStatic
fun isEmpty1(str: String): Boolean {
return "" == str
}
}
companion object{
fun isEmpty4(str: String): Boolean {
return "" == str
}
@JvmStatic
fun 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()
}
}