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

最后再来做个小实现:

Kotlin对象表达式要点与Lambda表达式的更多相关文章

  1. C#在泛型类中,通过表达式树构造lambda表达式

    场景 最近对爬虫的数据库架构做调整,需要将数据迁移到MongoDB上去,需要重新实现一个针对MongoDB的Dao泛型类,好吧,动手开工,当实现删除操作的时候问题来了. 我们的删除操作定义如下:voi ...

  2. Kotlin语法(函数和lambda表达式)

    三.函数和lambda表达式 1. 函数声明 fun double(x: Int): Int { } 函数参数是用 Pascal 符号定义的 name:type.参数之间用逗号隔开,每个参数必须指明类 ...

  3. C# LINQ查询表达式用法对应Lambda表达式

    C#编程语言非常优美,我个人还是非常赞同的.特别是在学习一段时间C#后发现确实在它的语法和美观度来说确实要比其它编程语言强一些(也可能是由于VS编译器的加持)用起来非常舒服,而且对于C#我觉得他最优美 ...

  4. 委托、 Lambda表达式和事件——Lambda表达式

    /* * 由SharpDevelop创建. * 用户: David Huang * 日期: 2015/7/30 * 时间: 16:32 */ using System; namespace Lambd ...

  5. C# Lambda表达式和linq表达式 之 匿名对象查询接收

    很多小伙伴都用过Lambda表达式和linq表达式,用起来也得心应手,但是有的小伙伴 对匿名对象的查询与接收比较迷茫,(没有定义相应的实体),怎么在where()里面进行 条件筛选呢?常规用法我就不说 ...

  6. 【C++】C++中的lambda表达式和函数对象

    目录结构: contents structure [-] lambda表达式 lambda c++14新特性 lambda捕捉表达式 泛型lambda表达式 函数对象 函数适配器 绑定器(binder ...

  7. 《疯狂Kotlin讲义》读书笔记6——函数和Lambda表达式

    函数和Lambda表达式 Kotlin融合了面向过程语言和面向对象语言的特征,相比于Java,它增加了对函数式编程的支持,支持定义函数.调用函数.相比于C语言,Kotlin支持局部函数(Lambda表 ...

  8. 1.1 为什么要使用lambda 表达式

    第1章 lambda 表达式 1.1 为什么要使用lambda 表达式 1.2 lambda 表达式的语法 1.3 函数式接口 1.4 方法引用 1.5 构造器引用 1.6 变量作用域 1.7 默认方 ...

  9. 深入学习C#匿名函数、委托、Lambda表达式、表达式树类型——Expression tree types

    匿名函数 匿名函数(Anonymous Function)是表示“内联”方法定义的表达式.匿名函数本身及其内部没有值或者类型,但是可以转换为兼容的委托或者表达式树类型(了解详情).匿名函数转换的计算取 ...

随机推荐

  1. [LeetCode] 283. Move Zeroes 移动零

    Given an array nums, write a function to move all 0's to the end of it while maintaining the relativ ...

  2. Bazel安装及使用入门

    Bazel [文档][https://docs.bazel.build/versions/1.1.0/bazel-overview.html] MacOS安装 brew tap bazelbuild/ ...

  3. SQL死锁情况汇总排查

    select dbname,entity_name,count(1) as locks from (SELECT request_session_id AS spid, DB_NAME(resourc ...

  4. Java开发笔记(一百四十一)JavaFX的列表与表格

    下拉框只有在单击时才会弹出所有选项的下拉列表,这固然节省了有限的界面空间,但有时候又需要把所有选项都固定展示到窗口上.像这种平铺的列表控件,Swing给出的控件名称是ListBox,而JavaFX提供 ...

  5. Linux命令xargs的使用

    ls | xargs catls | xargs -I {} cat {}  大写I,指定参数的替换符号为{} 自定义

  6. 2019/7/18ACM集训

    2019-07-18 09:15:34 这个是练习刷的题 Vus the Cossack and Numbers Vus the Cossack has nn real numbers aiai. I ...

  7. PB 计算公式算出结果赋值给另外一列

    在数据窗口中添加一个公式列 --在itmchanged事件中写的计算赋值代码 String ls_gs,ls_sqldecimal{2} ls_gsjg if dwo.name='gs1' then ...

  8. 【转】webpack4安装过程遇到的问题及处理方法

    随便百度一下,安装使用webpack的教程铺天盖地,安装一步步来,最后的最后打包没反应......,浪费了不少的时间. 这里我要提醒一下,如果安装webpack1,2,3按照百度上的教程应该不会有问题 ...

  9. 树莓派Raspbian系统格式化挂载硬盘

    1.查看树莓派系统挂载的储存设备 使用工具查看系统识别到的硬盘设备,命令: fdisk -l /dev/sda 和 /dev/sdb  分别是两块硬盘. 2.修改硬盘分区 Linux和windows一 ...

  10. 常用的MySQL命令

    1.新建数据库: create database person; 2.使用数据库 use person: 3.创建一个表格 create table student ( id int(10) not ...