22. 【Java教程】抽象类

简介: 22. 【Java教程】抽象类

本小节我们将学习 Java 中的抽象类,你将了解到抽象类的概念和特点,抽象类在程序设计时的应用场景,什么是抽象方法,抽象方法有什么特点,如何声明一个抽象方法等内容。

1. 概念和特点

在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。


值得注意的是,一个抽象类不能直接实例化,但类的其他功能依然存在;既然不能被实例化,那么它必须被继承才能被使用。

2. 为什么需要抽象类

当某个父类只知道其子类应该包含什么方法,但不知道子类如何实现这些方法的时候,抽象类就派上用场了。使用抽象类还有一个好处,类的使用者在创建对象时,就知道他必须要使用某个具体子类,而不会误用抽象的父类,因此对于使用者来说,有一个提示作用

例如,父类 Pet 被子类 CatDog 继承,并且都重写了父类的 eat 方法:

class Pet {
    // 定义方法 eat
    public void eat() {
        System.out.println("宠物都会吃东西");
    }
}
 
class Dog extends Pet { // 继承父类
    // 重写父类方法 eat
    @Override
    public void eat() {
        System.out.println("狗狗吃狗粮");
    }
}
 
class Cat extends Pet { // 继承父类
    // 重写父类方法 eat
    @Override
    public void eat() {
        System.out.println("猫猫吃猫粮");
    }
}

小猫类、小狗类这些子类都重写了宠物类中的 eat 方法,我们知道每种宠物都有吃的行为,宠物表示了一个抽象的概念。那么宠物类的实例化和方法调用就没有了实际意义:

1. PePet pet = new Pet();
pet.eat();

我们知道了抽象类不能被实例化,此时可以将父类设定为抽象类,使用 abstract 关键字来声明抽象类,abstract 关键字必须放在 class 关键字前面 :

// 声明抽象类
abstract class Pet {
    ...
}

如果你尝试实例化抽象类 Pet,编译器将会报错:

Pet.java:4: 错误: Pet是抽象的; 无法实例化
        new Pet();
        ^
1 个错误

使用抽象类,我们既可以通过父类和子类的继承关系,来限制子类的设计随意性,也可以避免父类的无意义实例化。

3. 抽象方法

抽象类中可以包含抽象方法,它是没有具体实现的方法。换句话说,与普通方法不同的是,抽象方法没有用 {} 包含的方法体。


抽象类可以定义一个完整的编程接口,从而为子类提供实现该编程接口所需的所有方法的方法声明。抽象类可以只声明方法,而不关心这些方法的具体实现,而子类必须去实现这些方法。

上面我们将 Pet 父类改为了抽象类,其中包含了 eat 方法的具体实现,而实际上这个方法是不需要具体实现的,每种宠物都有各自的具体实现。此时,就可以将 eat 方法改为抽象方法:

abstract class Pet {
    abstract void eat();
}

我们可以看到抽象方法使用 abstract 关键字声明,它没有方法体,而直接使用 ; 结尾。

子类必须实现父类中的抽象方法,假如 Dog 类继承了抽象类 Pet,但没有实现其抽象方法 eat

class Dog extends Pet {
}

编译执行代码,将会报错:

Dog.java:1: 错误: Dog不是抽象的, 并且未覆盖Pet中的抽象方法eat()
public class Dog extends Pet {
       ^
1 个错误

上述报错中可知,如果我们不想在 Dog 中重写抽象方法 eat(),那么可以将 Dog 也改为抽象类:

abstract class Dog extends Pet {
}

抽象方法不能是 final、static 和 native 的;并且抽象方法不能是私有的,即不能用 private 修饰。因为抽象方法一定要被子类重写,私有方法、最终方法以及静态方法都不可以被重写,因此抽象方法不能使用 private、final 以及 static 关键字修饰。而 native 是本地方法,它与抽象方法不同的是,它把具体的实现移交给了本地系统的函数库,没有把实现交给子类,因此和 abstract 方法本身就是冲突的。

4. 小结

可以使用 abstract 关键字声明抽象类或抽象方法。

抽象类不能被实例化,抽象类中的方法必须被非抽象子类实现,它必须被继承才能被使用。

抽象类中不一定包含抽象方法,但抽象方法一定在抽象类中。

相关文章
|
27天前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
5天前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
|
5天前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
5天前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
|
8天前
|
Java
Java基础(13)抽象类、接口
本文介绍了Java面向对象编程中的抽象类和接口两个核心概念。抽象类不能被实例化,通常用于定义子类的通用方法和属性;接口则是完全抽象的类,允许声明一组方法但不实现它们。文章通过代码示例详细解析了抽象类和接口的定义及实现,并讨论了它们的区别和使用场景。
|
10天前
|
Java 测试技术 开发者
Java零基础-抽象类详解
【10月更文挑战第17天】Java零基础教学篇,手把手实践教学!
10 2
|
13天前
|
Java 测试技术 开发者
Java零基础-抽象类详解
【10月更文挑战第15天】Java零基础教学篇,手把手实践教学!
17 2
|
14天前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
本指南介绍了如何在Spring Boot项目中集成Firebase云消息服务(FCM),包括创建项目、添加依赖、配置服务账户密钥、编写推送服务类以及发送消息等步骤,帮助开发者快速实现推送通知功能。
31 2
|
22天前
|
Java 数据库连接 编译器
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
|
24天前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
本系列教程笔记详细讲解了Kotlin语法,适合希望深入了解Kotlin的开发者。对于需要快速学习Kotlin的小伙伴,推荐查看“简洁”系列教程。本篇笔记重点介绍了Kotlin与Java混编的技巧,包括代码转换、类调用、ProGuard问题、Android库开发建议以及相互调用时的注意事项。
22 3