接口还是抽象类

    xiaoxiao2021-11-03  92

    很多人都有问过,为什么我们在刚刚学习ssh mvc的时候,是依赖接口注入而不是抽象类。要解答这个问题,我们需要了解接口和抽象类这两概念。

    1.在java编程思想中,抽象类的定义是包含抽象方法的类。

    public abstract class Bird { } 抽象类有三点要注意: 1>抽象类不能用于创建对象。 2>抽象方法必须用public 或protected来修饰。如果为private就不能被子类所继承,所以抽象方法用private修饰是无法通过编译的。在默认情况下抽象方法是public。 3>如果子类无法实现所继承父类的抽象方法,则子类必须为抽象类。

    2.接口,sun的设计初衷是对行为的抽象

    public interface Flyable { Long flight_mile= 100l; void fly(); } 接口特性: 1>接口中的变量都会被隐式地定义为public static final,方法会被隐式的定义为 public abstract。所以可以使用接口中的变量定义你的constant。 2>接口中所有成员必须为public。 3>抽象类实现接口,可以不用实现接口中的所有方法。

    我们把抽象类和接口的特性拿出来比较了。下面我们再把抽象类和接口放在一起看看:

    在宏观设计上: 1>抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部行为进行抽象。 2>抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计

    语法层面上的区别:

    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动态代理了。

    转载请注明原文地址: https://ju.6miu.com/read-677951.html

    最新回复(0)