接口与抽象类不同点
抽象类:可定义成员变量,可以有抽象方法也可以有普通方法,普通方法需要有方法体,抽象方法在继承类中实现,可定义构造器
接口:接口的变量都是静态常量,全部都是抽象方法,实现类都得实现,不可定义构造器,都是public方法
接口与抽象类使用场景
抽象类 多用于同类事物,描述该事物有什么特征,继承类将直接继承该特征,当公共方法可在抽象类中写具体实现,子类将继承到这个方法,避免重写。当子类与父类之间存在逻辑上的层次关系时,使用抽象类,
接口 多用于不同类之中,主要用于定义规范,行为约束
**抽象类对事物进行抽象,更多的是为了继承,为了扩展,为了实现代码的重用,子类和父类之间体现的是is-a关系;接口则更多的体现一种行为约束,一种规则,一旦实现了这个接口,就要给出这个接口中所有方法的具体实现,**也就是说实现类对于接口中所有的方法都是有意义的。
举个列子,现在要定义一个猫类和一个狗类,你可以直接定义两个类
class Cat{
private String color;
private String name;
public void shout(){
System.out.println("喵喵喵");
}
public void eat(){
System.out.println("吃饭啦");
}
}
class Dog{
private String color;
private String name;
public void shout(){
System.out.println("汪汪汪");
}
public void eat(){
System.out.println("吃饭啦");
}
}
这样设计完全可以,但是当某一天又要设计一个猪类呢,是不是又要重复以上的代码,这样是不利于代码的重用的,我们看到猫类和狗类都有名字和颜色属性,都有吃和叫这两个行为,那么是不是可以抽象出一个公共基类呢,这个公共基类和这些动物类的关系明显是is-a关系。由于猫和狗叫的方式不同,所以这个类不能是普通的类,只能是抽象类
abstract class BaseAnimal{
private String color;
private String name;
public abstract void shout();
public void eat(){
System.out.println("吃饭啦");
}
}
class Cat extends BaseAnimal{
public void shout(){
System.out.println("喵喵喵");
}
}
class Dog extends BaseAnimal{
public void shout(){
System.out.println("汪汪汪");
}
}
很明显这样实现了代码的重用,以后要设计一个猪类,只要继承BaseAnimal类并实现shout方法就可以了,而不用写那么多重复的代码,那么能不能把BaseAnimal定义成接口呢,而不是抽象类?肯定是不行的,先不说接口中不能定义color和name这两个域(接口的变量都是全局常量,不可改变),即使这些动物只有行为没有属性,也是不能把BaseAnimal定义成接口的,**这些动物都有一个共同的行为,就是吃饭,每个实现类都去实现一遍相同的代码是没有意义的。(因为接口方法实现类需要全部实现)**如果定义为接口,那么Cat类和Dog类是没办法扩展的,实现类要想扩展只能改变接口,使用抽象类,如果想要扩展猫类,直接修改猫类就行了,而狗类完全不受影响。
之前我们说了**,接口是一种约束和规则,一旦实现了某个接口,就必须实现这个接口中所有的方法,且这些方法对于这个类都是有意义的。**现在定义一个接口,接口中有两个方法,一个方法可以比较,一个方法显示动物的技能。当需要设计一个既可以比较又有技能的动物类时,只要实现这个接口,那就必定要实现这两个方法。没有接口,你可能设计出来的动物类只有技能,而忘了能比较这个功能。所以说,接口就是一份契约,由类实现契约。契约中我编写了某些大的方针与前提,而签了约的类可以具体问题具体分析来实现自己的功能
以后在考虑是使用接口还是使用抽象类的时候,只要根据自己实际的项目场景,根据这样设计的目的以及设计的合理性去选择。一般情况下,抽象类和接口是要同时使用的
为什么要使用接口
这主要还是看你项目的复杂程度,项目团队的水平和人数。如果你的项目是你一个人在做,或者两三个水平差不多的人在做,一个功能,从业务逻辑到数据访问都可以由同一个人完成,那么使用接口的意义就不是很大,因为这种需求明确,业务不是很复杂的系统,一旦完成基本是不会怎么改了,用接口反而增大任务量,而且接口设计还是挺有难度的,设计接口对于抽象能力有很高的要求,如果要更改实现类,还要去更改接口,那么这个接口肯定是不合理的;相反的,如果你的业务比较复杂,系统比较庞大,就需要有一个抽象能力很高的人来专门设计这个接口,他可以忽略实现的细节,把精力更多的花在设计上,这样效率会更高。如果你的团队水平有高有低,那么也是需要设计一个接口来统一规范的。其他程序员就可以按照这接口进行写实现类,因为有规范,需要实现的方法才不至于忘记写,还有一种情况就是项目人员很庞大,项目提交容易出错的情况下,也是需要用到接口的
接口的另一大好处就是体现多态性,来实现系统的解耦,使用接口调用实现类,如果需求发生改变,只要改变实现类就行,上层代码不需要做改变