抽象类(abstract class)的概念
使用abstract关键字来修饰的类就是抽象类,抽象类不能实例化,也就是说不能使用new关键字创建一个抽象类的实例;如果某个类是抽象类,那么该类可以包含具体的方法(有声明、有实现);
使用abstract修饰的方法叫做抽象方法。如果一个类中包含了抽象方法,那么这个类一定要声明成abstract class,也就是说该类一定是抽象类;反之,如果某个类是抽象类,那么该类既可以包含抽象方法,也可以包含具体方法。
例子
假如我们要通过多态来实现某人在某所学校上学,该人现在正在做某件事情!
通过分析我们发现有该问题有如下的类:
一个People类:该类有name属性,doSomething方法
一个School类:该类有name属性,study方法(接受People类的实例)
具体代码如下:
public class School {
private String name;
public School(String name)
{
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void study(People people)
{
System.out.println(people.getName() + "在" +this.name + "上学!");
}
}
public class People {
private String name;
public People(String name)
{
this.name = name;
}
public void doSomething()
{
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
现在我们先使用多态的方法来打印大学生张三在哈佛上大学!他正在教室敲代码!
因此我们需要创建一个Undergraduate类,让该类继承自People类。该类需要覆盖父类的doSomething方法,用于实现自己的业务逻辑。(这样便于扩展,假设又有一个高中生类的话,我们不需要修改School类的代码)。具体代码如下:
public class Undergraduate extends People
{
public Undergraduate(String name) {
super(name);
}
public void dosomething()
{
System.out.println(this.getName() + "正在教室敲代码!");
}
}
客户端代码如下:
public class Client {
public static void main(String[] args) {
School school = new School("哈佛");
People people = new Undergraduate("大学生张三");
school.study(people);
}
}
打印结果如下:
大学生张三在哈佛上学!
我们发现并没有打印大学生张三正在教室敲代码!因为子类的doSomething方法拼写错误,因此客户端并没有在子类中发现其对应的doSomething方法,因此调用了父类的空实现的doSomething方法。
为了避免这种不必要的麻烦,我们对子类加上约束条件,也就是采用抽象方法的形式来实现上述代码,我们改写People类的代码:
/**
* 抽象类:为开发人员规定一种约束
* 抽象类不能实例化
* @author asus
*
*/
public abstract class People {
private String name;
public People(String name)
{
this.name = name;
}
/**
* 定义了抽象方法,包含抽象方法的类必须是抽象类
* 抽象方法存在的意义:就是用来被子类所覆盖的;
*/
public abstract void doSomething();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
.在子类继承父类(父类是个抽象类),那么该子类必须要实现父类中所定义的所有的抽象方法。否则,该子类需要声明成一个abstract class。因此可以避免这种不必要的麻烦。
抽象类就是用来被继承的,抽象类等于为开发人员确定了相应的约束。抽象方法存在的意义就是用来被子类覆盖。
方法对于父类没有实现的意义,我们就将该方法定义成抽象方法。