2021-10-11 kotlin 对象声明、伴生对象、对象表达式

对象的声明:

① 创建类的同时创建一个对象

② 对象的属性和方法类似于类的静态方法和属性,可以通过对象.方法、对象.属性在外面调用。

③ 对象直接利用对象声明的该特性,将类的声明和实例的声明结合在一起,因为不能有其他方式创建对象,所以满足单例模式。

④ 对象的声明创建的实例只有一个。

当然你也可以定义一个变量来获取获取这个对象,当时当你定义两个不同的变量来获取这个对象时,
你会发现你并不能得到两个不同的变量。也就是说通过这种方式,我们获得一个单例。

object Site {
    
    
    var url:String = ""
    val name: String = "菜鸟教程"
}
fun main(args: Array<String>) {
    
    
    var s1 =  Site
    var s2 = Site
    s1.url = "www.runoob.com"
    println(s1.url)
    println(s2.url)
}

结果:

www.runoob.com
www.runoob.com
匿名内部类:

就是没有名字的类,使用场景一般是:需要创建只是用一次的类,

特点:匿名内部类因为是没有名字,所以肯定是不能有构造器,不能实例化的。

​ 同时因为没有名字,结构内容必须是继承某个父类或者是实现某个接口实现的,但是只能继承一个父类或者实现一个接口。

​ 不能是抽象类。

首先,定义一个匿名类要实现的接口,代码如下

public interface Product{
    
    
 double getPrice();
 String getName();

然后,定义一个实体类,实体类定义一个方法,方法的参数为上述的接口对象,到时候会传入一个匿名类对象,这个匿名类实现了上述创建的接口,代码如下

public class Anony{
    
    
	public void test(Product product){
    
    
	System.out.println("购买了一个"+product.getName()+",花掉了"+product.getPrice());
	}
}

最后测试运行:

pubic class Test{
    
    
	public static void main(String[] args){
    
    
		Anony anony=new Anony();
		// 注意,此处要传入一个匿名类对象
		anony.test(new Product(){
    
    
			@Override
			public double getPrice(){
    
    
					return 578.6;
				}
			@Override
			public String getName(){
    
    
					return "联想笔记本";
				}
			}
		);
	}
}

输出:

购买了一个联想笔记本,花掉了578.6

这里就是一个匿名内部类的例子,也就是说我并不想实例化一个product对象,如果我实例化一个对象,后续这个对象没有任何的用处,只是使用这一次,所以就是用的是匿名内部类。这里的匿名内部类实现一个接口。java在编译的时候把这个内部类当做是它实现的接口或者是继承的父类看待。

对象表达式 :

在java中如果想使用一个之对当前类有修改的对象,但是不想再创建该类的子类,就会使用匿名内部类来达到目的,只是用一次。在kotlin中,则是使用对象表达式和对象声明完成。

创建匿名类的方式: var xx = objec :接口、父类()。

比如:

valueAnimator.addUpdateListener(object :AnimatorUpdateListener {
    
    
    override fun onAnimationUpdate(animation: ValueAnimator?) {
    
    
        currentPoint = animation?.animatedValue as Point
        postInvalidate()
    }
})
伴生对象 companion object:

companion object实际上就是一个快捷方式,让我们可以通过类名访问该对象的内容,伴生对象中的方法和属性作为静态成分使用。

一个类中最多只能定义一个伴生对象。

对应的类加载的时候进行初始化的。

如果要在外进行调用使用的话:

如果声明伴生对象有名称,则使用

类名.伴生对象名.方法名()
类名.半生对象名.属性的setter,getter方法

例:NumberTest.Obj.plus(2, 3)
  • 如果声明伴生对象无名称,则采用 Companion 关键字调用:

    类名.Companion.方法名()
    类名.Companion.属性的setter,getter方法
    
    例:NumberTest.Companion.getFlag()
    
@JvmField 和 @JvmStatic 的使用:

刚刚说如果在外面进行调用则是使用 类名.伴生对象名.方法名 来进行调用,提供了@JvmField 和 @JvmStatic 进行注释,在外调用的时候就不用加上伴生对象名了,在属性上面使用@JvmField ,在方法上面使用 @JvmStatic。

const关键字

如果要声明一个静态常量,可以使用@JvmField 修饰,也可以使用const进行修饰

Guess you like

Origin blog.csdn.net/qq_45204129/article/details/120706880