🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# Java 抽象类和抽象方法 > 原文: [https://www.programiz.com/java-programming/abstract-classes-methods](https://www.programiz.com/java-programming/abstract-classes-methods) #### 在本教程中,我们将学习 Java 中的抽象。 我们将学习 Java 抽象类和方法,以及如何在程序中使用它们。 ## Java 抽象类 抽象类是无法实例化的类(我们无法创建抽象类的对象)。 在 Java 中,我们使用`abstract`关键字来声明一个抽象类。 ```java abstract class Animal { //attributes and methods } ``` 如果尝试创建抽象类的对象,则会出现编译错误。 例如, ```java Animal a1 = new Animal() ``` 它将产生一个编译错误: ```java Animal is abstract; cannot be instantiated ``` 尽管不能实例化抽象类,但是我们可以从中创建子类。 我们可以创建子类的对象来访问抽象类的成员。 在详细了解它之前,我们需要了解抽象方法。 * * * ## Java 抽象方法 我们使用相同的关键字`abstract`创建抽象方法。 声明了一个抽象方法而没有实现。 例如, ```java abstract void makeSound(); ``` 在这里,`makeSound()`是一种抽象方法。`makeSound()`的主体被`;`取代。 重要的是要注意,只有抽象类才能包含抽象方法。 如果我们在不是抽象的类中包含抽象方法,则会出现错误。 抽象类可以包含抽象方法和非抽象方法。 这是一个例子。 ```java abstract class Animal { public void displayInfo() { System.out.println("I am an animal."); } abstract void makeSound(); } ``` 在上面的示例中,我们创建了一个抽象类`Animal`。 它包含抽象方法`makeSound()`和非抽象方法`displayInfo()`。 * * * ## 抽象类的继承 抽象类无法实例化。 要访问抽象类的成员,我们必须继承它。 例如 ### 示例 1:抽象类的继承 ```java abstract class Animal { public void displayInfo() { System.out.println("I am an animal."); } } class Dog extends Animal { } class Main { public static void main(String[] args) { Dog d1 = new Dog(); d1.displayInfo(); } } ``` **输出**: ```java I am an animal. ``` 在上面的示例中,我们创建了一个抽象类`Animal`。 我们无法创建`Animal`的对象。 要访问`Animal`的`displayInfo()`,我们继承了`Animal`的子类`Dog`。 然后,我们使用`Dog`的`d1`对象访问方法`displayInfo()`。 * * * ## 覆盖抽象方法 在 Java 中,必须在子类中覆盖超类的抽象方法。 这是因为子类继承了超类的抽象方法。 由于我们的子类包含抽象方法,因此我们需要覆盖它们。 **注意**:如果子类也被声明为抽象,则不必强制覆盖抽象方法。 ### 示例 2:覆盖抽象方法 ```java abstract class Animal { abstract void makeSound(); public void eat() { System.out.println("I can eat."); } } class Dog extends Animal { public void makeSound() { System.out.println("Bark bark"); } } class Main { public static void main(String[] args) { Dog d1 = new Dog(); d1.makeSound(); d1.eat(); } } ``` **输出**: ```java Bark bark. I can eat. ``` 在上面的示例中,我们创建了一个抽象类`Animal`。 该类包含一个抽象方法`makeSound()`和一个非抽象方法`eat()`。 我们从超类`Animal`继承了子类`Dog`。 在此,子类`Dog`覆盖了抽象方法`displayInfo()`。 然后,我们创建了`Dog`的对象`d1`。 然后使用该对象调用`d1.displayInfo()`和`d1.eat()`方法。 * * * ## 访问抽象类的构造器 与非抽象类相似,我们使用`super`关键字从子类访问抽象类的构造器。 例如, ```java abstract class Animal { Animal() { …. } } class Dog extends Animal { Dog() { super(); ... } } ``` 在这里,我们已经使用`Dog`的构造器中的`super()`来访问`Animal`的构造器。 注意,`super`应该始终是子类构造器的第一条语句。 访问 [Java `super`关键字](https://www.programiz.com/java-programming/super-keyword)了解更多信息。 * * * ## 为什么选择 Java 抽象? 抽象是面向对象编程的重要概念。 抽象仅显示所需的信息,所有不必要的细节都保持隐藏。 这使我们可以通过使用更简单,更高级的想法省略或隐藏细节来管理复杂性。 抽象的实际示例可以是摩托车制动器。 我们知道刹车的作用。 当我们踩刹车时,摩托车将停止。 但是,制动器的工作对我们而言是隐藏的。 隐藏制动器工作原理的主要优点是,现在制造商可以为不同的摩托车实现不同的制动器,但是制动器的作用是相同的。 让我们举一个例子来帮助我们更好地理解 Java 抽象。 ### 示例 3:Java 抽象 ```java abstract class Animal { abstract void makeSound(); } class Dog extends Animal { public void makeSound() { System.out.println("Bark bark."); } } class Cat extends Animal { public void makeSound() { System.out.println("Meows "); } } class Main { public static void main(String[] args) { Dog d1 = new Dog(); d1.makeSound(); Cat c1 = new Cat(); c1.makeSound(); } } ``` **输出**: ```java Bark bark Meows ``` 在上面的示例中,我们创建了超类`Animal`。 超类`Animal`具有抽象方法`makeSound()`。 无法在`Animal`内部实现`makeSound()`方法。 这是因为每种动物都会发出不同的声音。 因此,`Animal`的所有子类都将具有`makeSound()`的不同实现。 我们无法以对`Animal`的所有子类都正确的方式在`Animal`中实现`makeSound()`。 因此,`Animal`中`makeSound()`的实现保持隐藏状态。 在以上示例中,`Dog`自行实现了`makeSound()`,而`Cat`自行实现了`makeSound()`。 * * * ## 要记住的要点 * 我们使用`abstract`关键字来创建抽象类和方法。 * 抽象方法没有任何实现(方法体)。 * 包含抽象方法的类也应该是抽象的。 * 我们不能创建抽象类的对象。 * 为了实现抽象类的函数,我们从其继承子类并创建该子类的对象。 * 子类必须覆盖抽象类的所有抽象方法。 但是,如果子类被声明为抽象的,则不必强制覆盖抽象方法。 * 我们可以使用抽象类的引用来访问抽象类的静态属性和方法。 例如 ```java Animal.staticMethod(); ``` * * * ## Java 接口 在 Java 中,接口类似于抽象类。 但是,接口没有任何非抽象方法。 在下一个教程中,我们将学习有关接口的更多信息。