之所以引入抽象类和抽象方法,是为了引导使用者正确使用它们,减少被误用。当抽象类中的方法被声明为抽象方法时,继承它的子类就知道需要实现该方法。
Java中类不能多继承类是为了安全。因为无论是抽象类还是非抽象类都包含非抽象的方法(非抽象类也可能没有),当类可以多继承类时,被继承的不同的父类可能会有同名同参的方法,如果子类也没有重写这个同名同参的方法,则在子类的实例调用这个方法的时候就会出现冲突。
简单实例,Employee是一个抽象类,其中有comptePay()为抽象方法,再
Salary继承抽象类,
public abstract class Employee {
private String name;
private String address;
private int number;
public abstract double computePay();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
public class Salary extends Employee
{
private double salary; // Annual salary
public double computePay()
{
System.out.println("Computing salary pay for " + getName());
return salary/52;
}
}
测试及输出
可以看到,抽象类不能实例化本类对象,只能通过继承它的子类声明子类对象。
前面我们介绍了抽象类,可以看到抽象类只支持单继承,而面对子类是由多个类的部分组合的情况下, 及比如食品类,饮品类,而套餐类里既有食品类下的具体食品又包含饮品类下的具体饮品。简单的说就是类似于多继承关系的实现,所以为了解决这种情况,提出了更加抽象的接口。
常见的,比如我们在使用Spring框架体系时,往往服务层是由接口和实现类实现的,通常有一个接口(server),再有一个业务类实现接口的具体方法(serverImpl)。
public interface InterDemo {
static final int sta = 10;
double getARandom();
void showThing();
}
public class ImplDemo implements InterDemo{
@Override
public double getARandom() {
return Math.random();
}
@Override
public void showThing() {
System.out.println(sta + "这是接口中定义的常量");
}
}
public class Main {
public static void main(String[] args) {
ImplDemo demo = new ImplDemo();
System.out.println(demo.getARandom());
demo.showThing();
}
}
注意:
- JDK 1.8 以后,接口里可以有静态方法和方法体了
- JDK 1.9 以后,允许将方法定义为 private,使得某些复用的代码不会把方法暴露出去。