一 抽象类
抽象类是一个用关键字abstract所修饰的类,该类只能作为父类被继承,而不能创建对象。抽象类的基本格式为:
访问权限修饰符 abstract class 类名{
// 类体
}
在抽象类中,可以存在一种特殊的方法:抽象方法。抽象方法是只有方法首部而没有方法体的方法(连花括号“{}”都没有),也需要使用abstract关键字,其基本格式为:
访问修饰符 abstract 返回类型 方法名(形参表);
抽象方法和抽象类的关系为:
- 一个类如果有抽象方法,该类就必须是抽象类,需要使用abstract关键字修饰
- 一个抽象类里可以有抽象方法,也可以有非抽象方法
- 子类若继承抽象类,需要对抽象方法进行重写,即完成抽象方法,如果子类没有重写抽象方法,则子类也是抽象类,必须用abstract修饰
【例1】定义Animal类为抽象类,同时完成子类Fish
public abstract class Animal {
public abstract void run();
public abstract void eat();
}
public class Fish extends Animal {
@Override
public void run() {
System.out.println("鱼在水中游……");
}
@Override
public void eat() {
System.out.println("鱼吃草……");
}
}
二 接口
接口是Java中一种特殊的引用类型,使用关键字interface定义,语法格式为:
访问权限修饰符 interface 接口名 {
// 接口体
}
在接口体里面可以定义常量和方法,但是每个常量会默认被public static final修饰(可省略),即接口中定义的常量都为公有的静态常量(必须显式赋初值,否则会出错),接口中定义的方法都是抽象方法,并默认被public abstract修饰(可省略)。
【例2】
public interface IDrawable {
// 省略public static final,编译器自动添加
int MAX = 100;
public static final int MIN = 0;
public abstract void draw(int x, int y);
boolean compare(int x, int y);
}
【例3】
public interface IFly {
public abstract void fly();
}
public class Airplane implements IFly { // 飞机类,实现接口
public void fly() {
System.out.println("飞机在天上飞……");
}
}
一个接口可以被多个接口继承,接口可以是公有的,也可以是默认访问权限(只能被包中的其他类访问)。
JDK8以后,允许接口中有static方法和default方法,方法中允许有默认的实现。
详细说明可参阅https://blog.youkuaiyun.com/aitangyong/article/details/54134385
三 接口和抽象方法的关系
从定义上来看,接口和抽象类都只能被类实现,而不能实例化。
从语法来看:
- 抽象类使用关键字class定义,接口使用关键字interface定义
- 抽象类中的成员可以是各种类型的,如私有变量、受保护变量等,而接口中的成员变量只能是公有静态常量(public static final)
- 接口中不能含有静态代码块,而抽象类中可以有静态代码块
从设计层面来看:
- 抽象类可以看成是多个对象共同抽象出的共性,是对行为和属性的抽象,是“类模板”,抽象类和子类之间是“is-a”关系
- 接口是对方法的抽象,不是对一类事物的抽象,属于“协议规范”