• 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,所以:

    最后再来做个小实现:

  • 相关阅读:
    HDU 1333 基础数论 暴力
    HDU 1299 基础数论 分解
    HDU 1211 EXGCD
    HDU 3507 单调队列 斜率优化
    博弈
    std:ios::sync_with_stdio(false);
    NBUT[1220] SPY
    nbut1217 Dinner
    poj2236Wireless Network
    ZOJ Problem Set
  • 原文地址:https://www.cnblogs.com/webor2006/p/11367636.html
Copyright © 2020-2023  润新知