1、定义
首先定义一个Person类,再定义Student类和Employee类。因为学生是一个人,员工也是一个人,所以让Student类和Employee类同时继承Person类。因为学生和员工都有姓名属性,所以可以将getName()方法放在公共的父类Person类中,两个子类都可以继承父类中的方法,就不需要子类再单独定义(尽量将通用的字段或方法放在父类中)。
此时,子类Student类和Employee类各自再增加一个getDescription()方法,该方法返回对一个人的姓名等简短描述。但是,在父类Person类中应该提供什么内容呢?父类Person类无法确定子类中的具体属性,所以若在父类中定义getDescription()方法,不知道返回具体什么内容。所以在父类中定义getDescription()方法时,可以使用关键字abstract,加上这个关键字之后,该方法就是抽象方法,就完全不需要实现这个方法了。同时,包含一个或多个抽象方法的类本身必须也要使用关键字abstract定义,该类就是一个抽象类。例:
public abstract class Person(){
.....
//该方法无需实现
public abstract String getDescription();
}
由于在抽象父类中定义的抽象方法没有具体实现,所以当子类继承父类时,子类必须实现父类中的抽象方法。例:
public class Student extends Person(){
.....
//在子类中具体实现该方法
public String getDescription(){
return "this is a student";
}
}
2、性质
-
抽象类不能实例化。当一个类使用关键字abstract声明时,就不能创建这个类的对象。例:
Person p = new Person();//错误
-
可以创建抽象类型Person的变量,但是这个变量只能引用其非抽象子类的对象。例:
Person p = new Student(...);
-
先看代码:
var people = new Person[2]; //将员工和学生对象填充到一个Person引用数组 people[0] = new Student(...); people[1] = new Employee(...); //输出对象的姓名和信息描述 for(Person p : people){ System.out.println(p.getName() + ", " + p.getDescription()) }
当大家看到p.getDescription()可能会有疑问,父类中并没有具体实现getDescription(),怎么可以调用呢?是这样的,由于不能构造抽象类的对象,所以p不会引用Person类对象,而是引用Student和Employee这样的具体子类的对象,从而调用子类中定义的方法。
此时大家会想,是否可以省略父类中的抽象方法,直接在子类Student和Employee中定义getDescription()方法呢?如果是这样的话,就不能在变量p上调用getDescription()方法了,因为只允许调用在类中声明的方法。