1、抽象方法和抽象类的介绍
面向对象的三大特征:封装、继承,和多态。
有了封装,我们数据和属性不再是零散的,有了set/get方法,很容易使用这些属性。
类多了以后,我们可以这些类的共同特征抽取出来,作为父类。用子类继承父类可以直接直接访问非私有的方法,使结构清晰,代码简便。如下:
然而,有一个问题,就比如这里父类中的work方法,Student和Teacher虽然都会工作,但工作内容是不同的(学生的work是学习,老师的work是教书)。所以,把work抽取给父类,方法到底如何写是一个问题。
也许Person父类的work方法是学习,那么老师类继承后要重写work方法;抑或Person父类的work方法是教书,那么学生类继承后要重写work方法。但这显然是不合理的。
于是有了抽象方法。把父类的work方法定义为抽象方法,子类继承后都需要重写,不然会报错。而抽象方法(哪怕只有一个)所在的类就是抽象类。
2、抽象类的定义格式
1)抽象类不能实例化,即不能创建对象。反过来思考,我们知道一个普通类中的方法要有方法体,而抽象类中的抽象方法是不需要方法体的(即不需要花括号{})。如果抽象类能创建对象,那么调用其中的抽象方法时,该执行什么?
2)Q:既然不能创建对象,那构造方法存在的意义是什么?
A:虽然父类是抽象类,但是子类在构造方法赋值时,引用的是父类的构造方法进行赋值的。所以父类虽然是抽象类,但是其构造方法有意义。
比如:Father类是一个抽象类,有构造函数
Father(String name){
this.name = name;
}
而子类Son继承父类,子类的构造方法是
Son(string name){
super(name);
}
3)抽象类的子类要么把继承的抽象类中的所有抽象方法重写,要么本身也是一个抽象类。
3、抽象类和方法的意义
Q:既然继承抽象类后,还要重写抽象方法,那为什么不直接去掉抽象方法,直接在每个子类中添加普通方法呢?这样不会更加节省代码吗?
A:在现实中,开发成员数量众多,每个人在继承父类后,如果自己编写方法,在其他人要调用时,还需要一个一个看每一个子类对应的方法到底是什么。就比如说这里的父类是Animal,在猫类继承后,吃方法定义为abc;狗类继承后的吃方法定义为eating,其他动物…这样以来,如果有其他成员想要调用猫类或者狗类的吃方法,还需要检查一下是如何定义的。但此时如何父类定义好了吃方法eat,此时不管是猫类还是狗类都需要强制重写eat方法,其他队员调用时,直接使用eat方法即可。这样统一了标准,使代码更加规范。