Java中接口和抽象类的区别

    这里说的都是在java8新特性之前的特点。因为在jdk1.7之前,接口是不允许定义方法体的,当然还有一些其他的特性,我这里就不一一列出了。我这篇文章还是说一哈jdk1.7之前的接口和抽象类的区别和联系。

抽象类

    基本的概念是什么我就不多说了。下面强调的都是我觉得比较重要的特性。
        1.抽象类的的方法必须全部都被子类实现,如果子类没有全部实现,那么子类也是抽象类。

        2.抽象类的方法不一定全部都是抽象的方法,有些方法是可以自己先实现,之后子类直接使用就好。也就是说,其实一个抽象类可以完全就是没有抽象方法,就只有在类名前面加上一个abstract就好。 但是这么做我觉得没有什么实际性的必要。

        3.抽象类不能创建实例对象,但是可以有自己的构造方法。这两者看上去似乎有些矛盾,但是其实也是合理的。因为抽象类是可以有自己的成员变量的,之后子类继承之后,还得调用父类的构造函数。

接口

    下面讨论的就是接口的特性。注意,这里说的是jdk1.7的特性。
        1.接口里面的方法也得全部被子类实现,如果没有实现的话,那么该类就只能被称作抽象类。

        2.承接第二点,因为如果没有完全实现一个接口的所有的方法,就会导致整个成为一个抽象类。也就是说,接口的实现是强制性的,但是抽象类的实现不是强制性的。就像java源码中也是这个样子在我们使用到监听器的时候,也是为了避免实现一个接口的所有的方法,我们往往会使用一个抽象类去实现这个接口。我记得这个抽象类去实现的时候好像都是空实现。注意,这里所说的空实现也得是函数的前面不能加上一个abstract修饰,不然加上一个空的方法体也是会报错的。然后要你自己的类去继承这个抽象类。那么,你就可以使用你自己想要的方法,而不用去实现你自己不想要的方法。这里也从侧面说明了在jdk1.7的时候,接口中的方法前面的public abstract ,属性前面的public static final都是默认的,你加不加都可以。但是不能改变该函数是一个abstract,所以在接口中方法仅仅只有一个方法体都是会报错的。

        3.其实接口可以间接性的创建对象。使用匿名内部类就是间接性创建了一个对象。

        4.接口里面也是可以有自己的成员变量的,但是默认都是public static final.也就是说,定义的时候就得赋初值。其实我这个理解的也不是特别深入。这里有一篇文章写到不错:http://developer.51cto.com/art/200906/130093.htm
还有这个文章上面的几句话我觉得说的挺有道理的:

接口就是提供一种统一的”协议”,而接口中的属性也属于“协议”中的成员。它们是公共的,静态的,最终的常量。相当于全局常量。抽象类是不“完全”的类,相当于是接口和具体类的一个中间层。即满足接口的抽象,也满足具体的实现。

通俗的讲,你认为是要变化的东西,就放在你自己的实现中,不能放在接口中去,接口只是对一类事物的属性和行为更高层次的抽象。对修改关闭,对扩展(不同的实现 implements)开放,接口是对开闭原则的一种体现。

如果还说服不了自己的话,还有一句话,这个我是在论坛上面看到的:Java本来就是强类型的语言。用sun的话来说就是“你喜欢你就用,不喜欢你就不用。”

设计接口的目的

    java工程师设计接口的目地是什么捏?我想别人这么设计肯定有他们的目的,好处。而且肯定是有利于项目的合作开发的。但是我也还只是一个学生,还是不太知道项目中接口的优点, 在和别人合作时的优点。但是有一点是可以告诉你的就是:如果Cat,Dog,Snake都继承了Animal,此时我想要在Dog,Snake类中增加一个bitePeople()的方法(因为dog和snake在现实生活中都是会咬人的)。如果你在Animal类中添加这个方法显然是不合适的,因为Cat类中是不需要这个方法的,因为cat是不会咬人的。所以现在怎么做?那么就只能在Dog类和Snake类中都添加这个方法。但是此时就是每一个类中就得都去实现以后就没有多态的效果了,因为Animal中就没有bitePeople()这个方法。 因为没有贴出具体的代码,所以大家不能理解的话,可以去看看下面的这个博主的文章,我觉得写的很好。具体的例子见链接:https://blog.csdn.net/JLongSL/article/details/54885780
所以此时接口的好处就来了。因为前面我们也说过,接口就是一个方法的抽象。而这里恰恰就可以使用 接口来实现。我们让Dog类和Snake类去实现Hunt这个接口就好了。然后也就可以实现多态了。

接口与抽象类的自己的一点总结

    抽象类的功能应该远远多于接口。但是定义抽象类的代价是比较高的。因为像java,C#这样的高级语言,是不允许多继承的所以,你在设计一个父类为抽象类的时候,一定得将这个类的子类所有的共同属性和方法都定义出来;但是接口可以不用这样。因为接口是一个方法的集合,一个类可以实现多个接口。所以,你的接口里面只有一个方法,还是两个方法,都是可以的。之后如果还有新的方法,我大不了再设计一个接口就是了。所以说,抽象类的设计必须谨慎,接口的设计很灵活。

你可能感兴趣的:(Java)