1Z0-809复习 第2章 设计模式和原则 Interface

Design Patterns and Principles

  • 会申明,实现,继承,接口,并且使用override注释
  • 会写lambda表达式
  • 会用java.util.function package里的
    Predicate,Function,Consumer,Supplier
  • 实现封装
  • 实现继承,包括可是修饰符和composition
  • 创建单例类和不可修改类

Designing an Interface

有时间复习一下OCA中关于interface的

Purpose of an Interface

Introducing Functional Programming

functional interface只有唯一抽象方法的接口。

Defining a Functional Interface

虽然不是必须,显示使用@FunctionalInterface来申明函数接口比较好。
如果已经标记了@FunctionalInterface注释,但接口中没有,或有多个抽象方法,
那么编译器会识别,报出编译错误。

另一问题是,如果不显示声明@FunctionalInterface
其他开发者有可能把这个接口当成函数接口用,某一天在这个接口中增加了一个方法之后,
其他开发者的程序会全部出错。

如果接口中只有一个抽象方法,那即使是有很多个default/static方法, 因为都不是抽象方法,整体上还是只有一个抽象方法,因此还是一个函数接口。

个人总结:函数接口是只有唯一一个抽象方法的接口。

Implementing Functional Interfaces with Lambdas

This expression means that Java should call a method with an Animal parameter that returns a boolean value that’s the result of a.canHop() . We know all this because we wrote the code. But how does Java know? 表达式意味着应该调用一个方法,这个方法参数是一个Animal类。并且返回一个boolean值(a.canHop的结果)。

Java relies on context when figuring out what lambda expressions mean.
java在判断lambda表达式时,是根据上下文来判断的。 We are passing this lambda as the second parameter of the print() method.
print的第二个参数是一个lambda表示。 That method expects a CheckTrait as the second parameter.
声明的地方,第二个参数是一个CheckTrait接口 Since we are passing a lambda instead, 不传入接口,而是传入一个lambda表达式, Java treats CheckTrait as a functional interface and tries to map it to the single abstract method: 于是java把checktrait当做一个functional interface。然后把表达式map到该函数接口的唯一的抽象方法。

Applying the Predicate Interface

Implementing Polymorphism

多态允许一个对象有多个形式,一个对象可以用自己本身类的参照,父类的参照,以及其实现的接口的参照来访问。
给一个对象指定了一个参照类型,那么只有这个参照类型里面定义了成员变量和方法可以被访问。

Distinguishing between an Object and a Reference

可以把对象想象成JRE在内存中分配的实体。

  1. 对象的类型决定了在内存中有哪些属性(这些属性是属于该对象的)。
  2. 参照的类型决定上述的属性(成员变量和方法)中哪些可以被访问。

根据参照类型,有些成员不能被访问,但可以通过显式的强制转换后来访问。

Casting Object References

Primate primate = lemur;
Lemur lemur2 = primate; // DOES NOT COMPILE
Lemur lemur3 = (Lemur)primate;
System.out.println(lemur3.age);
  1. 从子类转换到父类不需要显式的强制转换。
  2. 从父类转换到子类需要显式的强制转换。
  3. 编译器不许没有相关的类之间的互相转换。
  4. 就算是编译器没报错,如果对象不是该类型,那么还是会出runtime错。
public class Rodent {
}
public class Capybara extends Rodent {
    public static void main(String[] args) {
        Rodent rodent = new Rodent();
        //如果这样就不会出错,Rodent rodent = new Capybara();
        Capybara capybara = (Capybara)rodent; // Throws ClassCastException at runtime
    }
}

这个例子就不会出编译错,但是会出runtime错。
强制转成子类,也要从一开始这个对象就是子类才可以。

Understanding Design Principles

Encapsulating Data

Creating JavaBeans

boolean型的可以用is或者get,其他的类型只能是get/set

Applying the Is‐a Relationship

The is‐a relationship is also known as the inheritance test. The fundamental result of the is‐a principle is that if A is‐a B, then any instance of A can be treated like an instance of B.

Applying the Has‐a Relationship

Composing Objects

Working with Design Patterns

Applying the Singleton Pattern

public class HayStorage {
  private int quantity = 0;
  private HayStorage() {}
  private static final HayStorage instance = new HayStorage();
  public static HayStorage getInstance() {
    return instance;
  }
  public synchronized void addHay(int amount) {
    quantity += amount;
  }
  public synchronized boolean removeHay (int amount) {
    if(quantity < amount) return false;
    quantity -= amount;
    return true;
  }
  public synchronized int getHayQuantity() {
    return quantity;
  }
}
  1. 单例是私有的,静态的。
  2. 一般通过一个共有的getInstance方法来获取。
  3. 所有构造方法都是私有的。

因为所有的构造方法都是private的,所以Singleton类是final的。

Creating Immutable Objects

就是没有setter的JavaBean。

Using the Builder Pattern

Creating Objects with the Factory Pattern

Summary