public abstract class Bird { } 抽象类有三点要注意: 1>抽象类不能用于创建对象。 2>抽象方法必须用public 或protected来修饰。如果为private就不能被子类所继承,所以抽象方法用private修饰是无法通过编译的。在默认情况下抽象方法是public。 3>如果子类无法实现所继承父类的抽象方法,则子类必须为抽象类。
语法层面上的区别:
1>抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;
2>抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
3>接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
4>一个类只能继承一个抽象类,而一个类却可以实现多个接口。
综上我们了解了什么是接口什么是抽象类。下面我就讨论下为什么我在 spring的注入时要依赖接口。spring的ioc的基本原理是本剧配置文件,生产代理对象并提供对象的方法调用。aop也是通过配置产生代理对象再进行方法编织生成方法链按顺执行,这个以后再讲。
我们先来看看什么是代理模式。
1.静态代理。目标接口:
public interface FlyService { public void fly(); } 接口实现: public class FlyServiceImpl implements FlyService { @Override public void fly() { System.out.println("飞吧,喜鹊!"); } } 代理类:
public class FlyProxy implements FlyService{ FlyService service; public FlyProxy(FlyService service) { this.service = service; } public void fly() { service.fly(); } } 调用者: public class BusinessCenter { FlyService service; public void travel(){ FlyServiceImpl impl = new FlyServiceImpl(); service= new FlyProxy(impl); proxy.fly(); } } 代理的好处是在解耦的同时,也可以在代理方法中添加自己对方法前后都处理比如:
public class FlyProxy implements FlyService{ FlyService service; public FlyProxy(FlyService service) { this.service = service; } public void fly() { System.out.println("准备起飞."); service.fly(); System.out.println("好,降落吧!"); } } 这就是我们aop编程的原始想法。(后面再讲)
2.动态代理。 代理类:
public class DynamicProxy implements InvocationHandler { private Object target; @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result=null; result=method.invoke(target, args); return result; } public Object bind(Object target) { this.target = target; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } } 调用:
public class BusinessCenter { FlyService service; public void travel() { FlyServiceImpl impl = new FlyServiceImpl(); DynamicProxy proxy = new DynamicProxy(); service = (FlyService) proxy.bind(impl); service.fly(); } } 从此可以看出 JDK的动态代理依靠接口实现,如果有些类并没有实现接口,则不能使用JDK代理,这就要使用cglib动态代理了。