定义方式
- 抽象类:使用
abstract
关键字修饰,定义格式为 abstract class 类名 {... }
。
- 接口:使用
interface
关键字修饰,定义格式为 interface 接口名 {... }
。
成员变量
- 抽象类:可以有各种访问修饰符(
private
、protected
、public
等)的成员变量,也可以有 final
修饰的常量。例如:
abstract class AbstractClass {
private int privateVar;
protected String protectedVar;
public static final double PI = 3.14159;
}
- 接口:成员变量默认都是
public static final
类型的常量,必须在声明时初始化。例如:
interface MyInterface {
int DEFAULT_VALUE = 10;
}
成员方法
- 抽象类:可以有抽象方法(只有声明,没有实现,用
abstract
修饰)和具体方法(有方法体)。例如:
abstract class AbstractClass {
public abstract void abstractMethod();
public void concreteMethod() {
System.out.println("This is a concrete method.");
}
}
- 接口:JDK 8 之前,接口中的方法默认都是抽象的,且只能是
public abstract
,方法不能有方法体;JDK 8 开始可以有默认方法(用 default
修饰,有方法体)和静态方法(用 static
修饰,有方法体)。例如:
interface MyInterface {
void abstractMethod();
default void defaultMethod() {
System.out.println("This is a default method.");
}
static void staticMethod() {
System.out.println("This is a static method.");
}
}
继承与实现关系
- 抽象类:一个类只能继承一个抽象类,通过
extends
关键字实现继承。例如:
class SubClass extends AbstractClass {
@Override
public void abstractMethod() {
System.out.println("Implementation of abstract method.");
}
}
- 接口:一个类可以实现多个接口,通过
implements
关键字实现。例如:
class ImplementingClass implements MyInterface {
@Override
public void abstractMethod() {
System.out.println("Implementation of interface method.");
}
}
场景选择
- 优先选择抽象类的场景:
- 当存在一组相关的类,它们有一些共同的属性和行为,且这些行为中有部分需要具体实现,部分需要子类去定制时,使用抽象类。例如,在图形绘制系统中,
Shape
抽象类可以有 color
成员变量和 draw
抽象方法,Circle
和 Rectangle
等子类继承 Shape
并实现 draw
方法。
abstract class Shape {
private String color;
public Shape(String color) {
this.color = color;
}
public abstract void draw();
}
class Circle extends Shape {
private double radius;
public Circle(String color, double radius) {
super(color);
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Drawing a " + getColor() + " circle with radius " + radius);
}
private String getColor() {
return color;
}
}
- 优先选择接口的场景:
- 当需要实现某种功能,而这个功能与类的继承体系无关,或者希望一个类能同时具备多种功能时,使用接口。例如,在电商系统中,
Payable
接口可以定义支付相关的方法,Product
类和 Service
类都可以实现 Payable
接口来支持支付功能。
interface Payable {
void pay();
}
class Product implements Payable {
@Override
public void pay() {
System.out.println("Paying for the product.");
}
}
class Service implements Payable {
@Override
public void pay() {
System.out.println("Paying for the service.");
}
}