Java基础系列(十六):抽象类

本文详细解释了抽象类的概念及其在面向对象编程中的应用。通过具体的例子介绍了抽象类的特点、如何使用抽象方法以及如何创建抽象类数组。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为什么有抽象类

如果把类的继承结构看成一个金字塔,毫无疑问,位于金字塔顶端的父类更具有通用性,也会更加抽象,我们通常使用这个类来作为派生其他类的基类,而不是直接作为实例类。

比如,Tiger类和Rabbit类都是属于Animal类的一个子类,我们可以给他们一个getDescription()方法来对他们的特点进行描述,在Tiger类和Rabbit类中对于这个方法的实现很简单,只需要返回一个带有具体属性的字符串即可,比如:吃肉的小脑斧,吃素的小兔纸。但是Animal类中我们并不能确定这个动物是吃素还是吃肉,具体的实现需要看它的子类,这里我们可以让Animal类的这个方法返回一个空的字符串,当然,我们还有一个更好的做法,就是给这个方法加上abstract关键字,这样我们就可以不用对这个方法进行实现了。

    public abstract String getDescription();

为了提高程序的清晰度和代码的可读性,包含一个或多个抽象方法的类本身必须被声明为抽象的,也就是我们所说的抽象类

抽象类的特点
  1. 抽象类除了抽象方法以外,还可以包含具体数据和具体方法。比如,Animal类还保存着名字和一个返回名字的具体方法:
public abstract class Animal {

    private String name;

    public Animal(String name) {
        this.name = name;
    }

    public abstract String getDescription();

    public String getName() {
        return name;
    }
}

抽象方法相当于一个占位符,它的具体实现由子类来实现。继承一个抽象类有两种选择:

  • 在抽象类中定义部分抽象类方法或不定义抽象类方法,这样必须将子类也声明为抽象类。
  • 定义全部的抽象方法,子类可以不是抽象的。

    1. 一个类即使不含抽象方法,也可以将类声明为抽象类
    2. 抽象类不能被实例化,可以定义一个抽象类的对象变量,但是它只能引用非抽象子类的对象。
抽象类数组

我们先来看一个例子:

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:后续的课程中,我们会拿抽象类和接口做一个对比。


公众号

扫码或微信搜索Vi的技术博客,关注公众号,不定期送书活动各种福利~

image

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值