成员变量
- 抽象类:可以有各种访问修饰符的成员变量,包括private、protected、public等,成员变量可以是常量也可以是变量。例如:
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 class AbstractClass {
public abstract void abstractMethod();
public void concreteMethod() {
System.out.println("This is a concrete method.");
}
}
- 接口:方法默认都是public abstract的,在Java 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 {
protected 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 " + color + " circle with radius " + radius);
}
}
- 选择接口的场景:
- 当需要实现多继承的功能,或者定义一些行为的规范,而不关心具体实现细节时,使用接口。例如,在电商系统中,有
Payable
接口定义支付行为,Shipping
接口定义物流配送行为,商品类Product
可以同时实现这两个接口,来表明它既支持支付又支持配送。
interface Payable {
void pay();
}
interface Shipping {
void ship();
}
class Product implements Payable, Shipping {
@Override
public void pay() {
System.out.println("Product is being paid.");
}
@Override
public void ship() {
System.out.println("Product is being shipped.");
}
}