复用类
1.组合语法
定义:将对象的引用置于新类之中。
特性:编译器不是简单的对每个对象的引用都创建默认对象,若要初始化这些引用,可在代码的下列位置行:
- 在定义对象的时候
- 在类的构造器中
- 在正要使用这些类的时候。(惰性初始化,可以减少额外负担)
2.继承
2.1初始化基类
含有默认构造器的基类,在继承时编译器会自动调用默认构造器初始化基类,初始化的顺序是从基类向新类初始化,如果含有有参构造器时,新类的构造器要显示的调用基类的构造器,用关键字super来调用。
3.代理
3.1定义
Java没有提供对代理(Proxy)的支持,它是继承和组合的中庸之道。代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象,这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。
3.2 静态实现代理的方式
原理上讲实现代理的方式可以用继承和组合两种方法,但是组合相对继承来说更适用于代理。
3.3 JDK动态代理
动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。
for example
有个Moveable接口,汽车实现Moveabel接口的方法,但是想增加move的计时功能。可以通过JDK的动态代理来实现。
public interface Moveable {
public void move();
}
public class Car implements Moveable {
public void move() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("car start running");
}
}
public class TimeProxy implements InvocationHandler {
private Object Target;
TimeProxy(Object Target) {
this.Target = Target;
}
/**
* proxy 代理对象 method 代理方法 args 方法参数 Object 方法的返回值
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// before do some thing
long start = System.currentTimeMillis();
method.invoke(Target);
// after do some thing
long end = System.currentTimeMillis();
System.out.println("car is running " + (end - start) + " mm");
return null;
}
}
测试方法
public class TestTimeProxy {
public static void main(String[] args) {
Car car = new Car();
InvocationHandler h = new TimeProxy(car);
Moveable move = (Moveable) Proxy.newProxyInstance(car.getClass().getClassLoader(),
car.getClass().getInterfaces(), h);
move.move();
}
}
4.向上转型
现有类Transport和类Car,若Transport transport = new Car(); 称为向上转型。
5.final关键字
- final 修饰的基本数据是运行时被初始化,永不改变的。
- final 修饰的对象引用是恒定不变的,一旦引用被初始化指向一个对象,就无法再把它指向另一个对象。但是对象本身是可以改变的。
- 被static final 修饰的域只占一段不能改变的存储空间。