Java 核心技术卷Ⅰ (第十版 ) 第六章 接口、lambda表达式与内部类 (笔记)

1、接口

  • 接口技术:这种技术主要用来描述类具有什么功能。而并不是给出每个功能的具体实现。一个类可以实现一个或多个接口
  • 接口中的所有方法自动地属于public,接口中的域将自动设为public static final(无需手动添加)。
  • 接口绝对不能含有实例域和静态方法(但是java8允许增加静态方法,不是不合理只是违背接口抽象规范而已);但可以包含常量。
  • 接口不是类,不能通过new实例化一个接口;但是可以声明一个接口变量,然后将变量引用给接口的一个实现类.
  • Java 8 之后可以在接口中增添一个默认方法,必须用default修饰符标记这样的方法
    :如何解决默认方法冲突(如果先在一个接口中定义了一个默认方法,然后又在超类或者另一个接口定义了一个同样的方法)?
    - 超类优先。如果超类提供了一个具体方法,同名而且有相同参数类型的默认方法子类会被忽略(千万不要让一个默认方法重新定义Object类中的方法,由于类优先,导致无法超越Object这个类的方法)。
    - 接口冲突。如果一个超接口提供了一个默认方法,另一个接口提供了一个同名而且参数类型(不论是否是默认参数)相同的方法,子类必须覆盖这个方法来解决冲突。

2、接口实现类

  • Java对象无状态:无状态对象是没有实例字段(实例变量)的类的实例。 该类可能具有字段,但是它们是编译时常量(静态final)。
  • Java对象无状态:有状态对象是有实例字段(实例变量)的类的实例
这是一个无状态的对象:
class Stateless {
    void test() {
        System.out.println("Test!");   
        }
 }       
// 这也是一个无状态的对象:
class Stateless {
    //No static modifier because we're talking about the object itself
    final String TEST = "Test!";
    void test() {
        System.out.println(TEST);
    }
}
//Java对象无有状态
class Immutable {
    final String testString;

    Immutable(String testString) {
        this.testString = testString;
    }

    void test() {
        System.out.println(testString);
    }
}
  • clone():是Object 的一个protected方法,这说明你的代码不能直接调用这个方法;
    - 它对于一个对象一无所知,所以只能逐个域地进行拷贝。如果对象中的所有数据域都是数值或其他基本类型,拷贝没有任何问题
    - 但是如果对象包含子对象的引用,拷贝域就会得到相同子对象的另一个应用,这样一来,原对象和克隆的对象仍然会共享一些信息(浅拷贝)。

3、Lambda

  • 如果方法只有一个参数,而且这个参数的类型可以推导得出,则可以省略小括号

  • lambda表达式的返回类型总是由上下文推导得出

  • 如果一个lambda表达式只在某些分支返回一个值,而在另外一些分支不返回值,这是不合法的。例如:(x)->{if(x>1) return 1}

    3.1、函数式接口

  • 对于只有一个抽象方法的接口,需要这种接口对象时,就可以提供一个lambda表达式。这种接口称为函数式接口(我觉得这个定义有一些牵强)

  • 个人补充:函数式接口是 Java8 引入的一个新特性,是一种特殊的接口:SAM类型的接口(Single Abstract Method),但本质上还是接口。相比较于其他接口,函数式接口有且只能有一个抽象方法。只要接口中出现多个抽象方法,那么就不能称之为函数式接口,运行的时候就会报错。为此 Java8 提供了一个新的注解@FunctionalInterface,如果接口被这个注解标注,就说明该接口是函数式接口,如果有多于一个的抽象方法,在编译的时候就会报错。但是这个注解不是必需的,只要接口符合函数式接口的定义,那么这个接口就是函数式接口。(1、⽤于函数式接⼝类型声明的信息注解类型,这些接⼝的实例被 Lambda 表示式、⽅法引⽤或构造器引⽤创建。2、函数式接⼝只能有⼀个抽象⽅法,并排除接⼝默认⽅法以及声明中覆盖 Object 的公开⽅法的统计。3、同时,@FunctionalInterface 不能标注在注解、类以及枚举上。如果违背以上规则,那么接⼝不能视为函数式接⼝,当标注@FunctionalInterface 后,会引起编译错误。)
    在这里插入图片描述

3.2 方法引用、

  • 方法引用主要的三种情况:
    - object::instanceMethod
    - Class::staticMethod
    - Class::instanceMethod

3.3 变量作用域、

  • 在lambda表达式中,只能引用值不会改变的变量。lambda表达式中捕获的变量必须实际上是最终变量。(最终变量:这个变量初始化之后就不会再为它赋新值)
  • 在lambda表达式中声明与一个局部变量同名的参数或局部变量是不合法的。
  • 在一个lambda表达式使用this关键字时,是指创建这个lambda表达式的方法的this
    在这里插入图片描述
    this.toString()会调用Application对象的toString,而不是ActionListener的

4、内部类(后期在做详细补充,理解的不够透彻)

  • 内部类主要原因

    • 内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据
    • 内部类可以对同一个包中的其他类隐藏起来
    • 当想定义一个回调函数且不想编写大量代码时,可以使用匿名内部类比较便捷
  • 内部类既可以访问自身的数据域,也可以访问创建它的外围类对象的数据域。

  • 局部类不能用public和private访问说明符进行声明

5、代理(原书介绍的不算详细后期补充)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值