抽象与接口

JavaJavaBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

抽象(Abstraction)和接口(Interface)是 Java 中另外两个重要的概念。抽象类和接口虽然有一些共同点,但它们之间有很大的不同。开始这个实验,理解这些概念。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("`Java`")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["`Object-Oriented and Advanced Concepts`"]) java/ObjectOrientedandAdvancedConceptsGroup -.-> java/classes_objects("`Classes/Objects`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/oop("`OOP`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/abstraction("`Abstraction`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/interface("`Interface`") subgraph Lab Skills java/classes_objects -.-> lab-178542{{"`抽象与接口`"}} java/oop -.-> lab-178542{{"`抽象与接口`"}} java/abstraction -.-> lab-178542{{"`抽象与接口`"}} java/interface -.-> lab-178542{{"`抽象与接口`"}} end

抽象

抽象(Abstraction) 旨在建模和维护组织结构,它不会提供太多细节。细节留给 实现类 去补充。例如,当你考虑 Animal 的情况时,复杂的行为细节对用户是隐藏的。因此,每个具体的动物都会自行实现这些细节;我们只需要调用方法即可。在面向对象编程(OOP)中,抽象是一个向用户隐藏实现细节的过程。用户只会获得功能信息,而不会知道功能是如何实现的。换句话说,用户将知道对象能做什么,而不是它如何做。在 Java 中,抽象是通过抽象类和接口来实现的。

我们使用关键字 abstract 来声明一个抽象类。抽象类可以包含或不包含抽象方法(只有声明而没有实现的方法)。但是,如果一个类至少有一个 abstract 方法,那么该类必须声明为 abstract。如果一个类被声明为抽象类,则它不能被实例化。要使用抽象类,你必须在另一个类中继承它,并为其抽象方法提供实现。如果你继承了一个抽象类,你必须为其所有抽象方法提供实现。另一种使用抽象类的方式是调用其 类方法static 方法)。

示例:

将以下代码写入 /home/labex/project/abstractTest.java 文件中:

// 抽象类
abstract class Animal{
    // 抽象方法
    public abstract void grow();
}

abstract class Bird extends Animal{
    /*
     * 这个类继承了 Animal,
     * 但没有实现 Animal 的抽象方法 grow(),
     * 因此这个类也必须声明为抽象类,
     * 抽象类不能被实例化。
    */

    // 这个类有一个具体方法
    public void sing(){
        System.out.println("I'm singing a song...");
    }
}
class Dog extends Animal{
    // 在这个类中,我们必须实现抽象方法,否则子类必须保持抽象。
    public void grow(){
        System.out.println("I'm dog, I grow up.");
    }
}
public class abstractTest{
    public static void main(String[] args){
        Dog dog = new Dog();
        dog.grow();
    }
}

输出:

使用以下命令运行 abstractTest.java 文件:

javac /home/labex/project/abstractTest.java
java abstractTest

查看输出:

I'm dog, I grow up.

接口

接口(Interface)是抽象方法的集合。这意味着 interface 中的所有方法都是 abstract 的。接口不包含任何构造函数。接口不能包含实例字段;接口中只能有静态(static)和最终(final)字段。接口不能被类继承(extend),只能被类实现(implement)。一个接口可以扩展多个接口,一个类可以实现多个接口。

示例:

将以下代码写入 /home/labex/project/interfaceTest.java 文件中:

// 使用关键字 interface 创建接口。
interface myInterface1 {
    // 接口中的变量默认是 public、static 和 final 的。
    String NAME = "Interface";

    // 方法默认是 abstract 和 public 的。
    public void method1();
}
interface myInterface2 {
    // 我们可以显式地将接口中的变量定义为 public、static 和/或 final,或者像 myInterface1 那样直接定义。
    public final String ID = "1001";

    public void method2();
}
// myInterface3 包含 myInterface2 的方法,它从 myInterface2 扩展而来。
interface myInterface3 extends myInterface2{
    public void method3();
}
// 类 interfaceTest 必须实现上层接口的所有三个方法。
public class interfaceTest implements myInterface1,myInterface3 {
     /*
     * 这个类有三个来自三个接口的方法
     * 同时也获取了两个接口的变量
     */
    // 实现 method1()
    public void method1(){
        System.out.println("implement method1.");
    }
     // 实现 method2()
    public void method2(){}
     // 实现 method3()
    public void method3(){}
    public static void main(String[] args){
        // 测试方法
        interfaceTest test = new interfaceTest();
        test.method1();
        test.method2();
        test.method3();
        System.out.println("I have properties:" + interfaceTest.NAME +", " +interfaceTest.ID);
    }
}

输出:

使用以下命令运行 interfaceTest.java 文件:

javac /home/labex/project/interfaceTest.java
java interfaceTest

查看输出:

implement method1.
I have properties:Interface, 1001

总结

抽象类和接口可以解耦类,并为我们提供更清晰的设计思路。它们都不能直接实例化。抽象类仅支持单继承,而接口支持多继承,并且一个类可以实现多个接口。它们都提供了多态的一些特性,这是下一个实验的主题。

您可能感兴趣的其他 Java 教程