抽象类和接口
抽象类
public abstract class Figure {
public abstract void onDraw();
}
public class Ellipse extends Figure {
@Override
public void onDraw() {} // 实现(覆盖)
}
public class Triangle extends Figure {
@Override
public void onDraw() {}
}
public class HelloWorld {
public static void main(String[] args) {
Figure f1 = new Triangle();
f1.onDraw();
Figure f2 = new Ellipse();
f2.onDraw();
}
}
抽象方法中只有方法的声明,没有方法的实现。
如果一个方法被声明为抽象方法,这个类也必须声明为抽象类。
一个抽象类中,可以有0-n个抽象方法,以及0-n个具体方法。
设计抽象方法的目的就是让子类来实现。
抽象类不能被实例化,只有具体类才能被实例化。
(在UML类图中,抽象类和抽象方法的字体是斜体的)
接口
接口中所有的方法都是抽象的。(java8之后接口中增加了默认方法)
接口可以有成员变量。
(在UML类图中,接口的图标是I(i),类的图标是C)
public interface Figure {
// 接口中静态成员变量
String name = "几何图形";
void onDraw();
}
public class Ellipse implements Figure {
@Override
public void onDraw() {}
}
implements前面的修饰符是public(在任何地方访问)或省略(只能在当前包中访问)。
接口中成员变量都是静态成员变量(省略了public static final)
实现多个接口时,之间用逗号(,)隔开。
实现接口时要实现接口中声明的所有方法。
接口与抽象类一样都不能被实例化。
java中只允许继承一个类,但可以实现多个接口。
java中允许接口和接口之间继承。但其实在接口中覆盖方法没有实际意义,因为它们都是抽象的,都是留给子类实现的。
java8-新特性-默认方法-静态方法
java8之前接口不足:
- 不能可选实现方法。必须实现接口中全部方法,纵使有些方法不需要。
- 没有静态方法。
public interface InterfaceA {
void methodA();
String methodB();
// 默认方法
default int methodC() {
return 0;
}
// 默认方法
default String methodD() {
return "这是默认方法";
}
static double methodE() {
return 0.0;
}
}
public class ABC implements InterfaceA {
@Override
public void methodA() {}
@Override
public String methodB() {
return "实现methodB方法";
}
@Override
public int methodC() {
return 500;
}
}
// 调用时
// 声明接口类型,对象是实现类,发生多态
InterfaceA abc = new ABC();
实现接口时接口中原有的抽象方法在实现类中必须实现。
默认方法可以根据需要有选择的实现(覆盖)。
静态方法不需要实现,实现类中不能拥有接口中的静态方法。
抽象类与接口类区别
- 接口支持多继承,而抽象类(包括具体类)只能继承一个父类。
- 接口中不能有实例成员变量,接口所声明的成员变量全部是静态常量。抽象类与普通类一样,各种形式的成员变量都可以声明。
- 接口中没有包含构造方法。因为没有实例成员变量也就不需要构造方法。抽象类可以有实例成员变量,也需要构造方法。
类)只能继承一个父类。 - 接口中不能有实例成员变量,接口所声明的成员变量全部是静态常量。抽象类与普通类一样,各种形式的成员变量都可以声明。
- 接口中没有包含构造方法。因为没有实例成员变量也就不需要构造方法。抽象类可以有实例成员变量,也需要构造方法。
- 抽象类中可以声明抽象方法和具体方法。(java8之前接口中只有抽象方法,之后接口中也可以声明具体方法,具体方法通过声明默认方法实现)