接口还是抽象类

很多人都有问过,为什么我们在刚刚学习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动态代理了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值