Java(三十)Abstract 抽象类

​ 抽象类的由来

 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。例如,前面我们讲到Animal动物类,Cat,Dog都继承于Animal类

public class Animal {
    private String name;
    private String color;
    public void eat(){
        System.out.println("eat");
    }
    public void run(){
        System.out.println("run");
    }
}


public class Cat extends Animal {
 
    public void run(){
        System.out.println("run");
    }
}
public class Dog extends Animal {
  
 
    public void run(){
        System.out.println("run");
    }
}

我们会发现

第一:Animal到底什么是动物,它没有具体的行为和属性。new出来有什么意义,对于Animal类,是,所有的动物都有吃喝的行为,定义eat方法可以描述动物“吃”这一行为,但是每种动物吃的都不一样,因此一个eat方法并不能准确描述吃什么,怎么吃。这时Animal给出的信息就不足够描述一个对象,我们就不能去实例化Animal类,再比如有一个People人类,Student,Teacher是人类的子类,那什么是人类没有意义。

第二:我们看到Animal类有eat的方法,吃是每个动物必须有的,但是Dog和Cat确没有实现

如果说下面的子类不是你写的,而是别人写的,别人在写子类的时候,忘记重写了 work() 方法,或者就是故意不重写,你拿他有办法吗?那怎么办呢?抽象类就是专门治它们而存在的。

如果一个方法抽取到父类中,不确定方法体,就可以使用 abstract(抽象关键字) 去修饰,这个方法就叫做抽象方法。

抽象方法子类必须强制重写,否则子类的代码直接报错。

而抽象方法所在类,就是 抽象类,这就是 抽象类 的由来。

抽象类的定义及规则

在Java中,我们通过在类前添加关键字abstract(抽象的)来定义抽象类。如下所示 : 

抽象类的定义格式:直接给类名加上 abstract(抽象关键字) 就行了。

public abstract class 类名{}

抽象方法的定义格式:不写方法体,直接分号结束。

前面再加一个 abstract(抽象关键字)public abstract 返回值类型 方法名(参数列表);

必须使用Abstract关键字修饰含有0个或多个用abstract修饰的方法(抽象方法)抽象方法没有方法体,注意不能new

abstract class Animal {
    private String name;
    private String color;
    public abstract void eat();//如果一个方法已经确定是抽象方法,那么它绝不能再有方法体,即不能出现大括号,而是只需要在()后面添加一个分号即可
    public void run(){
        System.out.println("run");
    }
}

public static void main(String[] args) {
    new Animal();//不能new
}

一个类继承了抽象类,必须重写完抽象类的所有抽象方法,否则该类只能定义为抽象类。用abstract关键字修饰 ,

抽象类中不一定包含抽象方法,但拥有抽象方法的类必须定义成抽象类。  如果某个类继承了一个抽象类,那么这个类有两个选择——要么实现父类所有的抽象方法,要么子类本身也定义成抽象类。

abstract class Dog extends Animal{
    public void eat() {
    }
}

抽象类体现的是模板思想,部分实现,部分抽象。

当父类需要定义一个方法,却不能明确该方法的具体实现细节时,可以将该方法定义为abstract,具体实现细节延迟到子类

抽象方法不能被final private,static修饰,因为抽象方法需要在子类中进行重写。

再来看一个例子

假设左边的 Cat 是第一个程序员开发的,这个程序员在开发的时候他觉得:吃的方法叫什么名字,我想不起来了,方法名就使用 abc 代替。然后猫吃东西不能每次都吃一样的吧?所以方法需要加上一个形参,表示是猫吃的东西。完整代码如下图的左边。

假设右边的 Dog 是第二个程序员开发的,这个程序员在开发的时候他觉得:狗吃完了需要排除,因此这个程序员给这个方法加上了一个返回值。完整代码如下图的右边。

乍一看这个程序员写的代码,一点问题也没有。

但是两个程序员的代码合在一起,问题就出现了:假设第三个程序员,想要调用 吃东西 的方法,那就变的麻烦起来了。

如果他想要调用 猫 吃东西的方法,它就需要到 Cat类 中看一下吃东西的方法是哪个;

如果他想要调用 狗 吃东西的方法,它就需要到 Dog类 中看一下吃东西的方法是哪个;

如果这个Javabean的体系越来越大,每次第三个程序员调用eat方法的时候,到要到对应的子类去看一下你的 eat 方法是怎么写的,他才能去调用。

因此这种方式会导致代码不统一,以后在调用的时候非常的痛苦,有一种浑身蛋疼的感觉。

2)解决方案
假如我将共性的内容放到父类,其中方法体不一样的,我把它写成抽象的。那么子类在继承动物的时候,它就需要强制去重写这个方法。

以后别人在调用的时候,就不需要去看子类了,而是只需要直接去看父类就可以了。知道父类中的 eat() 方法是怎么定义的,就可以去调用所有子类中的 eat() 方法了。

同时这种方式,它还有一个隐藏的含义:强制子类必须按照这种格式进行重写,因此这种方式,它相当于就是有一种 将代码格式统一 的味道在里面。

抽象类的作用是什么?

当我们在多个子类中抽取共性时,如果在父类中无法确定方法体,就可以把这个方法定义为抽象的。

强制让子类按照这种格式进行重写。

抽象方法所在的类,必须写成抽象类。

例子

例子2

游戏管理器的改进,假设每个游戏情况不同,而且肯定是不同的,如果checkedNetWork这些方法写在父类里,出现什么问题,子类不是强制实现的。怎么解决使用抽象方法来解决

通过抽象类的使用,我们可以把需要子类必须定义的自身独有的方法,定义为抽象类,把共有的方法放在抽象类里去实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛定谔的猫1981

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值