MST
星途 面试题库

面试题:Java中抽象类与接口异同的中等难度考察

请详细阐述Java中抽象类和接口在成员变量、成员方法、继承与实现机制方面的异同点,并举例说明在实际开发场景中如何根据这些特点来选择使用抽象类还是接口。
13.2万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

成员变量

  • 抽象类:可以有各种访问修饰符的成员变量,包括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(部分实现或全部抽象),具体的图形类如CircleRectangle继承自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.");
    }
}