Java 基础知识记录(二)

149 阅读3分钟

接口、lambda表达式与内部类

  1. 接口中的所有方法都自动是public。不过,在实现接口时,必须把方法声明为public;否则,编译器将认为这个方法的访问属性是包可见性。

  2. 与接口中的方法都自动被设置为public一样,接口中的字段总是public static final。

  3. 尽管每个类只能有一个超类,但却可以实现多个接口。如果希望自己设计的类拥有克隆和比较的的能力,只要实现这两个接口就可以了:

    class Employee implements Cloneable, Comparable
    
  4. 为什么要引入接口的概念,为什么不将Comparable直接设计成一个抽象类呐?

    每个类只能扩展一个类(Java中不支持多重继承),假如Employee类已经扩展了另一个类,例如Person,它就不能再扩展第二个类了。 但每个类可以实现多个接口。

  5. 可以为接口方法提供一个默认实现。必须用default修饰符标记这样一个方法。

    public interface Comparable<T>{
        default int compareTo(T other) { return 0; }
    }
    

    Comparable的每一个具体实现都会覆盖这个方法。不过,有时候默认方法可能很有用,比如实现类可以不覆盖这个默认方法,接口中 有这个默认方法的实现逻辑,实现类可以不用操心实现这个方法了。

  6. 解决默认方法冲突:

  • 超类优先。如果超类提供了一个具体方法,同名而且有相同参数类型的默认方法会被忽略。

  • 接口冲突。如果一个接口提供了一个默认方法,另一个接口提供了一个同名而且参数类型(不论是否是默认参数)相同的方法,必须覆盖这个方法来解决冲突。

  1. 如果一个 lambda 表达式只在某些分支返回一个值,而另外一些分支不返回值,这是不合法的。例如:

(int x)-> {if(x>=0) return 1} 就不合法。

  1. 为什么要使用内部类?
  • 内部类可以对同一个包中的其他类隐藏。
  • 内部类方法可以访问定义这个类的作用域中的数据,包括原本私有的数据。
  • 内部类原先对于简洁的实现回调非常重要,不过如今 lambda 表达式在这方面可以做的更好。

  1. 一个内部类方法可以访问自身的数据字段,也可以访问创建它的外围类对象的数据字段。
  • 为此,内部类的对象总有一个隐式引用,指向创建它的外部类对象。

  1. 静态内部类: 有时候,使用内部类只是为了把一个类隐藏在另外一个类的内部,并不需要内部类有外围类对象的一个引用。为此,可以将内部类声明为 static,这样就不会生成那个引用。