MST
星途 面试题库

面试题:Java接口默认方法与抽象类的抉择问题

假设你正在设计一个Java类库,部分功能需要一些通用的默认实现,同时又需要一些子类去重写特定行为。你会在什么情况下选择使用接口的默认方法,什么情况下选择使用抽象类?请详细说明两者的优缺点,并举例代码说明在实际场景中的应用。
43.0万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

接口默认方法

  • 适用场景:当需要为接口提供一些通用的默认实现,且不希望强制所有实现类都必须继承自特定的类时,使用接口默认方法。它允许在不破坏现有实现类的情况下,向接口添加新的方法。
  • 优点
    • 实现多继承的效果,一个类可以实现多个接口,每个接口都可以有默认方法。
    • 方便在接口演进时添加新功能,不影响已有的实现类。
  • 缺点
    • 接口的默认方法不能包含状态(成员变量),限制了功能的复杂性。
    • 当多个接口的默认方法有冲突时,实现类需要解决冲突。
  • 示例代码
interface Shape {
    double getArea();

    default void printInfo() {
        System.out.println("This is a shape.");
    }
}

class Circle implements Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

抽象类

  • 适用场景:当存在一些通用的行为和状态,需要由子类继承并可能重写部分行为时,使用抽象类。它适用于定义具有公共属性和行为的对象层次结构。
  • 优点
    • 可以包含成员变量和具体方法,实现更复杂的逻辑。
    • 子类通过继承抽象类,自然地获得公共属性和方法,代码复用性高。
  • 缺点
    • Java 不支持多继承,一个类只能继承一个抽象类,限制了继承结构。
    • 当抽象类发生变化时,可能影响所有子类。
  • 示例代码
abstract class Animal {
    protected String name;

    public Animal(String name) {
        this.name = name;
    }

    public void eat() {
        System.out.println(name + " is eating.");
    }

    public abstract void makeSound();
}

class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }

    @Override
    public void makeSound() {
        System.out.println(name + " barks.");
    }
}