Kotlin对象表达式要点与Lambda表达式

Kotlin对象表达式要点揭密:

在上一次https://www.cnblogs.com/webor2006/p/11352421.html中学习了Kotlin的对象表达式,它主要是解决Java中匿名内部类的问题,这次继续对它进行学习,在上一次的示例中,我们定义了一个不继承任何类或实现任何接口的对象表达式,回忆如:

当时说该代码看似简单,其实里面有一些很隐晦的东东接下来阐述一下:

嗯,很简单,那接下来改一个东东就会让你觉得难以理解了:

报异常了。。这是为啥呢?这就是之前提出的“隐晦”处了,这里会涉及到对象表达式的一些注意事项及要点,下面来说明一下:

1、匿名对象只能在局部变量范围内或者被private修饰的成员变量范围内才能被识别出来其真正的类型,其中“被识别出真正的类型”的含义是指能正常的调用匿名内部类中的方法或成员变量,比如我们之前定义在局部变量范围的匿名对象:

所以它是能被正常识别出真正类型的,而目前咱们新定义的这个如果是被private修饰的话也是能被识别真正类型:

而如果将private关键字去掉之后,在Kotlin中默认在类中的访问级别就会变为public了,所以该匿名对象是不能被识别出真正的类型的,所以也就如我们所看到的报错了。

2、如果将匿名对象当做一个public方法的返回类型或是public属性的类型,那么该方法或是属性的真正类型就是该匿名对象所声明的父类型,如果没有声明任何父类型,那么其类型就是Any;在这处情况下,匿名对象中所声明的任何成员都是无法访问的。

回到咱们的这个程序理解一下这句话,也就是如果我们当private关键字去掉之后,会变为public属性类型了,此时它真正的类型就是该匿名对象的父类型,而根据“如果没有声明任何父类型,那么其类型就是Any”,也就是说:

为了进一步论证这个理论,咱们可以将myObject的类型打出来:

另外打印类型还有另外一种写法,了解一下:

 

接下来再来定义一个类进一步再来感受这个对象表达式的注意事项:

我们知道对于Java的匿名内部类中的方法想要访问外层类的变量,该外层类的变量一定得要声明为final才行,但是对于Kotlin的对象表达式而言是没有这个限制的,下面来用程序验证一下:

实际案例:

我们知道在Java的GUI编程中就会用到很多的匿名内部类,因为要监听控件的事件,下面则先用Java原滋原味的展现一下,然后稍后再用Kotlin的对象表达式将其改造,最后再来做一个对比,如下:

package com.kotlin.test3;

import javax.swing.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

public class JFrameTest {
    public static void main(String[] args) {
        JFrame jFrame = new JFrame("My JFrame");
        JButton jButton = new JButton("My JButton");

        jFrame.addWindowListener(new WindowListener() {
            @Override
            public void windowOpened(WindowEvent e) {
                System.out.println("windowOpened");
            }

            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("windowClosing");
            }

            @Override
            public void windowClosed(WindowEvent e) {

            }

            @Override
            public void windowIconified(WindowEvent e) {

            }

            @Override
            public void windowDeiconified(WindowEvent e) {

            }

            @Override
            public void windowActivated(WindowEvent e) {
                System.out.println("windowActivated");
            }

            @Override
            public void windowDeactivated(WindowEvent e) {

            }
        });

        jFrame.add(jButton);
        jFrame.pack();
        jFrame.setVisible(true);
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

然后运行:

然后咱们可以给Button增加一个点击事件:

还可以将其改为Lambda表达式,如下:

很简单的代码,接下来咱们用Kotlin的方式来实现同样的功能:

好,继续:

好,接下来是来设置可见性,在Java中是这样写的:

而在Kotlin中如果我们敲setVisible会自动匹配其它的一个名称,如下:

会自动变为isVisible,也就是Kotlin中推荐是用属性的方式来代替Java中的set和get方法,如下:

当我们点击查看时,自动会链接到setVisible()方法中:

其中还有一个小细节需要注意,其实在Window中的属性名不是isVisible,而是:

这也就说明了,对于boolean类型的变量,Kotlin会自动将其翻译成is开头的,好程序继续:

接下来给按钮增加点击事件:

Kotlin Lambda表达式:

关于Java的Lambda表达式已经很清楚了,也就是如果对象是Java函数式接口的一个实例(既只拥有一个抽象方法的接口),那么可以通过Lambda表达式来调用,其中Lambda表达式前面加上接口的类型。下面来对上面的Button的点击事件改成Kotlin的Lambda表达式,看跟Java的Lambda表达式有啥不一样:

但是!!其实还可以简化,从上面可以看出“ActionListener”被IDE标灰了,看一下它的提示:

其实这个ActionListener可以由Kotlin的编译推断出来,因为addActionListener方法接收的参数类型就是ActionListener,所以:

最后再来做个小实现:

原文地址:https://www.cnblogs.com/webor2006/p/11367636.html