Java基础系列(十六):抽象类
时间:2022-06-17
本文章向大家介绍Java基础系列(十六):抽象类,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
为什么有抽象类
如果把类的继承结构看成一个金字塔,毫无疑问,位于金字塔顶端的父类更具有通用性,也会更加抽象,我们通常使用这个类来作为派生其他类的基类,而不是直接作为实例类。
比如,Tiger类和Rabbit类都是属于Animal类的一个子类,我们可以给他们一个getDescription()方法来对他们的特点进行描述,在Tiger类和Rabbit类中对于这个方法的实现很简单,只需要返回一个带有具体属性的字符串即可,比如:吃肉的小脑斧,吃素的小兔纸。但是Animal类中我们并不能确定这个动物是吃素还是吃肉,具体的实现需要看它的子类,这里我们可以让Animal类的这个方法返回一个空的字符串,当然,我们还有一个更好的做法,就是给这个方法加上 abstract
关键字,这样我们就可以不用对这个方法进行实现了。
public abstract String getDescription();
为了提高程序的清晰度和代码的可读性,包含一个或多个抽象方法的类本身必须被声明为抽象的,也就是我们所说的抽象类
抽象类的特点
- 抽象类除了抽象方法以外,还可以包含具体数据和具体方法。比如,Animal类还保存着名字和一个返回名字的具体方法:
public abstract class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
public abstract String getDescription();
public String getName() {
return name;
}
}
抽象方法相当于一个占位符,它的具体实现由子类来实现。继承一个抽象类有两种选择:
- 在抽象类中定义部分抽象类方法或不定义抽象类方法,这样必须将子类也声明为抽象类。
- 定义全部的抽象方法,子类可以不是抽象的。
- 一个类即使不含抽象方法,也可以将类声明为抽象类
- 抽象类不能被实例化,可以定义一个抽象类的对象变量,但是它只能引用非抽象子类的对象。
抽象类数组
我们先来看一个例子:
public abstract class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
public abstract String getDescription();
}
public class Tiger extends Animal {
public Tiger(String name) {
super(name);
}
@Override
public String getDescription() {
return "A Tiger named " + getName() + " eat meat";
}
}
public class Rabbit extends Animal {
public Rabbit(String name) {
super(name);
}
@Override
public String getDescription() {
return "A Rabbit named " + getName() + " eat carrot";
}
}
public class AnimalTest {
public static void main(String[] args) {
Animal[] animals = new Animal[2];
animals[0] = new Tiger("awo");
animals[1] = new Rabbit("miao");
for (Animal animal : animals) {
System.out.println(animal.getDescription());
}
}
}
输出结果:
A Tiger named awo eat meat
A Rabbit named miao eat carrot
由于不能构造抽象类Animal的对象,所以变量animal永远不会引用Animal对象,而是引用诸如Tiger和Rabbit这样的具体子类对象,而这些对象中都定义了getDescription方法,所以打印出的结果分别是两个子类的实现,但是我们不能省略父类中的抽象方法,而仅在子类中定义,如果这样的话,我们就不能通过变量p调用getDescription方法,编译器只允许调用在类中声明的方法。
PS:后续的课程中,我们会拿抽象类和接口做一个对比。
下节预告
Object
- 如何用R语言从网上读取多样格式数据
- C/C++——生成随机数
- PHP基础——PHP数组
- 使用shell抽取html数据之二(r2笔记75天)
- Python爬取链家网数据:新房楼盘价格分析
- 【编程基础】Java里面如何对字符串排序?
- 计算广告——广告定向实践
- 通过shell抓取html数据(r2笔记74天)
- 通过shell脚本分析足彩(r2笔记74天)
- 通过shell脚本得到数据字典的信息 (r2笔记72天)
- 机器学习算法实践——K-Means算法与图像分割
- 利用 Python、SciKit 和文本分类来构建客户行为描述模型
- 使用Python爬取社交网络数据分析
- PHP爬虫源码:百万级别知乎用户数据爬取与分析
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- Spring源码学习笔记(7)——使用@Import导入组件
- 深度强化学习(DQN-Deep Q Network)之应用-Flappy Bird
- Could not load driverClass ${jdbc.driver}
- Js通过值获取索引下标
- Spring源码学习笔记(8)——Bean的生命周期
- hibernate系列之一
- Flutter定义tabbar底部导航路由跳转
- hibernate系列之二
- Flutter配置路由组件抽离及页面传参
- Spring源码学习笔记(9)——AOP
- spring笔记二
- spring中的AOP
- hibernate对单表的增删改查
- hibernate多表查询
- log4j的常用使用方法