抽象(abstract)
使用 abstract 修饰的类称为抽象类,使用 abstract 修饰的方法称为抽象方法
抽象方法只有方法的声明,没有方法体,如
public abstract double test();
特点
- 抽象类不能实例化对象,只能作为父类派生子类
- 抽象类不一定包含抽象方法(抽象类包含 n 个 抽象方法,n >= 0),但包含了抽象方法的类一定是抽象类
- 非 abstract 方法可以调用 abstract 方法
- 由抽象类派生的非抽象子类,必须覆盖父类中的所有抽象方法
- 抽象类是要先有子类,然后才抽象出父类,是一种从下往上的构建法则
- 抽象类中有构造函数。如果抽象类是父类,需要给子类提供实例的初始化
不能与 abstract 共存的关键字
- 抽象方法不能和 static 关键字共存,因为一旦使用 static 就可以通过类名直接访问抽象方法,由于抽象方法没有方法体,这样做没有任何意义,也不允许这样做
- 抽象方法不能和 final 关键字共存,因为被final修饰的类不能有子类。而被abstract修饰的类一定是一个父类。
- 抽象方法不能和 private 关键字共存,因为使用 private 就表明该方法是抽象类中的私有的抽象方法,不被子类所知,就无法被重写。而抽象方法出现的就是需要被重写。
抽象的目的
在面向对象软件开发中,抽象是指从众多的事物中抽取出共同的、本质性的特征,而舍弃其非本质的特征
- 抽象类进一步描述了多个具体类的共同特征和行为,可以更好地刻画自然界的抽象概念,并且减少代码的冗余,提高程序的开发效率
- 由于用 abstract 关键字修饰的抽象类派生出的子类必须实现其父类中的抽象方法,因此提高了代码的规范性,避免因程序员的失误而忘记实现抽象方法
接口(interface)
接口是一个更纯的抽象类,即它不能含有非 abstract 方法,变量
public interface demo {
int num;
void test();
}
特点
- 接口里面定义的方法被自动赋予 public abstract
- 接口里面定义的属性被自动赋予 public static final
- 在接口中声明方法时,不能使用 native, static, final, synchronized, private, protected 等修饰符
- 一个非抽象类实现了接口,必须实现接口里的所有抽象方法
- 一个类可以实现多个接口,一个接口可以继承多个接口
使用接口的目的
- 因为 Java 不像 C++ 一样支持多继承,所以Java可以通过实现接口来弥补这个局限
- 接口也被用来实现解耦
- Java接口是定义混合类型的理想工具,混合类表明一个类不仅仅具有某个主类型的行为,而且具有其他的次要行为。
抽象类和接口的区别
- 从设计层面上看,抽象类提供了一种 IS-A 关系,那么就必须满足里式替换原则,即子类对象必须能够替换掉所有父类对象。而接口更像是一种 LIKE-A 关系,它只是提供一种方法实现契约,并不要求接口和实现接口的类具有 IS-A 关系。
- 从使用上来看,一个类可以实现多个接口,但是不能继承多个抽象类。
- 接口的字段只能是 static 和 final 类型的,而抽象类的字段没有这种限制。
- 接口的成员只能是 public 的,而抽象类的成员可以有多种访问权限。
- Java接口和Java抽象类最大的一个区别,就在于Java抽象类可以提供某些方法的部分实现,而Java接口不可以,这是Java抽象类的优点,如果向一个抽象类里加入一个新的具体方法时,那么它所有的子类都一下子都得到了这个新方法,而Java接口做不到这一点,如果向一个Java接口里加入一个新方法,所有实现这个接口的类就无法成功通过编译了