如果自下而上在类的继承层次结构中上移,位于上层的类更加具有通用性,甚至可能更加抽象.从某中角度看,祖先类更加通用,人们只将它作为派生其他类的基类,而不作为想使用的特定的实例类.例如:考虑一下Employee类层次的扩展.一名雇员是一个人,一名学生也是一个人.将Preson和Student类添加到层次结构中,则Person为父类,Employee和Student都是Person的子类.
现在每个人都有一些诸如姓名这样的属性.学生与雇员都有姓名属性,因此可以将getName方法放在父类Person总.现在,再增加一个getDescription方法,它返回对一个人的剪短描述.
在Employee类和Student类中实现这个方法很容易.但是在Person类中应该提供什么样的内容呢?除了姓名之外,Person类一无所知.当然,可以让Person.getDescription()返回一个空字符串.然而,还有一个更好的方法,就是使用abstract关键字,这样就完全不需要实现这个方法了.
public abstract String getDescription();
为了提高程序的清晰度,包含一个或多个抽象方法的类本身必须被声明为抽象类
public abstract class Person{
....
public abstract Sting getDescription();
}
除了抽象方法之外,抽象类还可以具体数据和具体方法.例如,Person类还保存者姓名和一个返回姓名的方法
public abstract class Person{
private String name;
public Person(String name){
this.name = name;
}
public abstract String getDescription();
public String getName() {
return name;
}
}
抽象方法充当着占位的角色,他们的具体实现在子类中.扩展抽象类可以有两种选择
- 一种是在抽像类中定义部分抽象类方法或不定义抽象类方法,这样就必须将子类也标记为抽象类
- 另一种是定义全部的抽象方法,这样一来,子类就不是抽象的了.
例如:通过扩展抽象Person类,并实现getDescription方法来定义Student类.由于在Student类中不再含有抽象方法,所以不必将这个类声明为抽象的.
类即使不含抽象方法,也可以声明为抽象类.
抽象类不能被实例化.也会是说将一个类声明为abstract,就不能创建这个类的对象例如:表达式:
new Person("Vu")
是错误的,但是可以创建一个具体子类的对象.
需要注意,可以定义一个抽象类的对象变量,但是它只能引用非抽象子类的对象.例如:
Person p =new Student("vu","heelo")
这里的p是一个抽象类Person的变量,Person引用了一个非抽象子类Student的实例