------- android培训、java培训、期待与您交流! ----------
一)概述:
1、抽象类(abstract class):一般仅用于被子类继承。当多个类出现相同功能时,但功能主体不同,这样可以向上抽取,抽取时只抽取功能定义,而不抽取功能主体。也就是说,我们在从下往上看继承这个体系结构时,位于上层的类要比下层更具有通用性,也就是说更加抽象,即最上层的祖先(即超类)最具通用性。这时只讲上层的类作为遗传(或者说派生)下层类的基本的类,而不考虑特定的实例对象。
2、接口(interface):用来建立类与类之间关联的标准
接口可理解为一种特殊的抽象类(但不是),当抽象类中的方法全为抽象的
(即不包含任何非抽象方法),可通过接口表示。
二)联系:
1.其实接口是抽象类的延伸,可以将它看做是纯粹的抽象类,就是说接口比抽象类还抽象。
2、抽象类和接口都必须被一个类(子类)复写里面的全部抽象方法。
3、接口和抽象类都不可创建对象,因为其中含有抽象方法,需要被子类实现后,
对接口中抽象方法全覆盖后,子类才可以实现实例化。
三)具体区别:
-->实现
子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。
子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现
-->构造器
抽象类可以有构造器;接口不能有构造器
-->与正常Java类的区别
除了你不能实例化抽象类之外,它和普通Java类没有任何区别
接口是完全不同的类型
-->访问修饰符
抽象方法可以有public、protected和default这些修饰符
接口方法默认修饰符是public。不可以使用其它修饰符。
-->main方法
抽象方法可以有main方法并且我们可以运行它
接口没有main方法,因此我们不能运行它。
-->多继承
抽象方法可以继承一个类和实现多个接口
接口只可以继承一个或多个其它接口
-->速度
抽象类比接口速度要快
接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。
-->添加新方法
如果往抽象类中添加新的方法,可以给它提供默认的实现。因此不需要改变现在的代码。
如果往接口中添加方法,那么就必须改变实现该接口的类。
四)什么时候使用抽象类和接口:
如果拥有一些方法并且想让它们中的一些有默认实现,那么就使用抽象类。
如果想实现多重继承,那么必须使用接口。由于Java不支持多继承,子类不能够继承多个类,但可以实现多个接口。因此就可以使用接口来解决它。
如果基本功能在不断改变,那么就需要使用抽象类。如果不断改变基本功能并且使用接口,那么就需要改变所有实现了该接口的类。
五)Java8中的默认方法和静态方法:
Java 8增加了两个新的概念在接口声明的时候:默认和静态方法。默认方法和Trait有些类似,但是目标不一样。默认方法允许我们在接口里添加新的方法,而不会破坏实现这个接口的已有类的兼容性,也就是说不会强迫实现接口的类实现默认方法。
默认方法和抽象方法的区别是抽象方法必须要被实现,默认方法不是。作为替代方式,接口可以提供一个默认的方法实现,所有这个接口的实现类都会通过继承得到这个方法(如果有需要也可以重写这个方法),看看下面的例子:
private interface Defaulable {
// Interfaces now allow default methods, the implementer may or may not implement (override) them.
default String notRequired() {
return "Default implementation";
}
}
private static class DefaultableImpl implements Defaulable {
}
private static class OverridableImpl implements Defaulable {
@Override
public String notRequired() {
return "Overridden implementation";
}
}
接口Defaulable使用default关键字声明了一个默认方法notRequired(),类DefaultableImpl实现了Defaulable接口,没有对默认方法做任何修改。另外一个类OverridableImpl重写类默认实现,提供了自己的实现方法。
Java 8 的另外一个有意思的新特性是接口里可以声明静态方法,并且可以实现。例子如下:
private interface DefaulableFactory {
// Interfaces now allow static methods
static Defaulable create( Supplier< Defaulable > supplier ) {
return supplier.get();
}
}
补充:抽象类的一个用途是“模板方法设计模式”。(待续。。。)