返回

Java抽象类与接口之间的微妙差别

Android

1. 继承与实现

  • 抽象类: 抽象类是用来从属关系的父类。子类可以通过继承的方式来扩展抽象类,并获得抽象类中定义的方法和属性。
  • 接口: 接口不是父类,它是一种类型或契约。类可以通过实现接口的方式来实现接口中定义的方法。一个类可以实现多个接口。

2. 成员声明

  • 抽象类: 抽象类可以有三种成员变量:
    • 普通变量: 与普通类变量类似,可以有各种访问控制符(public, protected, default, private)。
    • 抽象变量: 声明了一个变量,但没有提供实现,其子类必须提供实现。
    • 常量: 与普通类常量类似,具有final。
  • 接口: 接口中所有的成员变量都必须是常量,并具有public和static这两个访问控制符。

3. 方法声明

  • 抽象类: 抽象类可以有三种方法声明:
    • 普通方法: 与普通类方法类似,可以有各种访问控制符。
    • 抽象方法: 声明了一个方法,但没有提供实现,其子类必须提供实现。
    • final方法: 具有final关键字,不能被子类重写。
  • 接口: 接口中所有的方法声明都是抽象的,即没有方法实现,只有方法签名。

4. 访问控制符

  • 抽象类: 抽象类中的成员变量和方法都可以有不同的访问控制符。
  • 接口: 接口中的成员变量和方法都必须具有public和static这两个访问控制符。

5. 多态

  • 抽象类: 抽象类可以通过多态来实现方法的重写。
  • 接口: 接口可以通过多态来实现方法的实现。

6. 代码示例

// 抽象类
abstract class Shape {
    // 普通变量
    private String name;

    // 抽象变量
    protected abstract double getArea();

    // 常量
    public static final double PI = 3.14;

    // 普通方法
    public void printName() {
        System.out.println(name);
    }

    // 抽象方法
    public abstract double getPerimeter();

    // final方法
    public final void draw() {
        System.out.println("Drawing a shape");
    }
}

// 接口
interface Drawable {
    // 常量
    public static final int RED = 0xFF0000;
    public static final int GREEN = 0x00FF00;
    public static final int BLUE = 0x0000FF;

    // 抽象方法
    public abstract void draw();
}

// 具体类
class Circle extends Shape implements Drawable {

    private double radius;

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

    @Override
    public double getPerimeter() {
        return 2 * PI * radius;
    }

    @Override
    public void draw() {
        System.out.println("Drawing a circle");
    }
}

public class Main {

    public static void main(String[] args) {
        Shape circle = new Circle(5.0);
        circle.printName();
        System.out.println("Area: " + circle.getArea());
        System.out.println("Perimeter: " + circle.getPerimeter());
        circle.draw();

        Drawable circle2 = new Circle(10.0);
        circle2.draw();
    }
}

希望这篇博客能帮助您更好地理解抽象类和接口之间的区别。如果您还有其他问题,请随时提出。