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在内存中分配的实体。
- 对象的类型决定了在内存中有哪些属性(这些属性是属于该对象的)。
- 参照的类型决定上述的属性(成员变量和方法)中哪些可以被访问。
根据参照类型,有些成员不能被访问,但可以通过显式的强制转换后来访问。
Casting Object References
Primate primate = lemur;
Lemur lemur2 = primate; // DOES NOT COMPILE
Lemur lemur3 = (Lemur)primate;
System.out.println(lemur3.age);
- 从子类转换到父类不需要显式的强制转换。
- 从父类转换到子类需要显式的强制转换。
- 编译器不许没有相关的类之间的互相转换。
- 就算是编译器没报错,如果对象不是该类型,那么还是会出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; } }
- 单例是私有的,静态的。
- 一般通过一个共有的getInstance方法来获取。
- 所有构造方法都是私有的。
因为所有的构造方法都是private的,所以Singleton类是final的。
Creating Immutable Objects
就是没有setter的JavaBean。