在教程(十二)中,我们有这样的假设。假设有这样一个简单需求(其实谈 不上是需求,仅仅为了初学者容易理解而编造):某培训中心要开发一个内部员 工管理系统。该培训中心目前有两个部门,技术资源部和业务部。技术资源部的 员工负责讲课,称为讲师。业务部员工负责联系洽谈业务,称为销售。在管理系 统中,需要管理的是所有员工的姓名、薪水,以及讲师的技术方向,销售的任务 量。
基于这样的假设,我们设计了三个类:父类Employee、子类Sales和Trainer 。如果我们有如下语句:
Employee e=new Employee();
是完全符合语法的。但是,我们从面向对象编程的角度出发,系统中存在的 对象,一定在现实中可以找到对应的实体。但是在现实中,是没有Employee类的 对象的,只有Sales,或者Trainer。所以得出结论:Employee类不应该被实例化 。
如何保证一个类不被实例化哪?只要将这个类声明为抽象类即可。使用 abstract关键字即可,如下:
public abstract class Employee {
private String name;
private double salary;
//TBC
}
Employee类声明为抽象后,将不能实例化,如果出现如下语句:Employee e=new Employee();将会出现编译错误。
但是抽象类依然可以作为类型使用,如:Employee e=new Sales();(后续文 章中将介绍该用法)。
初学者可以暂时把抽象类定义为:不能实例化的类,为抽象类。
接下来我们来考虑另外一个问题。
父类Employee中定义了一个方法:
public void setSalary(double salary,double rate) {
this.salary = salary*(1+rate);
}
但是如果子类Sales和Trainer虽然都需要实现这个业务逻辑,但是实现方式 却都不相同,如Sales如下:
public void setSalary(double salary, double rate) {
this.salary = salary*(1+2*rate);
}
Trainer类的如下:
public void setSalary(double salary, double rate) {
this.salary = salary*(1+0.5*rate);
}
那么,Employee类中的setSalary(double salary,double rate) 该如何处理?初学者往往会想,既然子类都不会使用父类的方法体,那么就直接 取消该方法的声明。这样是不可行的,父类是子类共同特别的体现,子类中确实 都需要实现setSalary(double salary,double rate)这个逻辑,只是实现方式不 同而已。也就是说,我们需要一个方案,既能够体现子类的共同特征,又不用写 出没用的方法体,这就是抽象方法。只要将父类的setSalary(double salary,double rate)方法声明为如下即可:
public abstract void setSalary(double salary,double rate) ;
需要注意的是,抽象方法是没有方法体的,声明后直接使用;结束。
抽象方法和抽象类之间的关系是:
1) 抽象类中不一定有抽象方法
2) 有抽象方法的类一定是抽象类
因此,如果一个类继承的父类中有抽象方法,那么子类必须实现其抽象方法 ,否则子类也必须声明为抽象类。
很多初学者会不太理解抽象类的作用,尤其抽象方法,觉得既然连实现逻辑 都没有,又何必声明?抽象类,抽象方法都是java中非常重要的概念,抽象类是 多个子类共同特征的体现,抽象方法是子类共同行为的规范。
¥399.00
¥498.00
¥299.00
¥29.00