在类的继承体系中,父类抽象出所有子类的共同特征(属性或者方法),有的功能子类直接继承即可,但是有些功能则不然,虽然是子类都具备的,但是具体的实现是不一样的,这些方法可以通过方法重写来实现,但是如果子类没有重写而直接继承的话可能会导致错误。例如,项目chapter4中定义的HisGraph类,提供了求图形的面积和周长的具体方法,默认实现返回值都为0,如果子类His Triangle3中忘记重写父类这两个方法,那么子类His Triangle3将继承父类这两个方法,这显然是不合理的。不同图形(例如圆、三角形、矩形、梯形等)求面积和周长的公式是不同的,无法统一具体实现。
在面向对象程序设计中,如果设计的类中有的方法的具体实现由它的子类确定,那么可以在父类中将这些方法声明为抽象方法。抽象方法是一些只有方法声明,而没有具体方法体的方法,一般存在于抽象类或接口中。注意,抽象方法没有方法体,而不是方法体为空。相应地,拥有抽象方法的类被称为抽象类。在抽象类中定义抽象方法,是在告诉子类,如果子类不是抽象类,则必须要实现抽象类中的全部抽象方法,这是一种强制约束。
在Java中,通过关键字abstract来声明一个抽象类或抽象方法。
【例4-8】
将HisGraph类改写成抽象类。
在项目chapter4下新建cn.linaw.chapter4.demo02包,在包下定义一个抽象类Her Graph,如图4-25所示。
图4-25 抽象类Her Graph
关于抽象类,注意以下几点:
(1)有抽象方法的类一定是抽象类,但是反过来说不对,抽象类中可以包含抽象方法,也可以不包含任何抽象方法。只要是abstract关键字修饰的类一定是抽象类。
(2)所有的抽象类相比普通类都不能被实例化。抽象类意味着该类不是一个完全具体或明确的类,因此不能实例化对象。但是,抽象类可以有它的构造方法,通过子类的构造方法调用,对抽象类的属性初始化。由于抽象类的构造方法只能被子类调用,因此可以将构造方法的访问权限设置为protected。构造方法不能声明为抽象方法。
(3)抽象方法一定是实例方法,不能是静态方法。静态方法归属于类,通过类名直接调用,因此,静态方法必须是具体的,不能声明为抽象方法。(www.xing528.com)
(4)抽象方法不能为private控制权限,否则子类无法实现,默认为public。抽象方法中public abstract关键字可以省略。
【例4-9】
子类Her Triangle1继承抽象类Her Graph,并实现了父类的所有抽象方法。
子类Her Triangle1继承自抽象类,而且实现了父类所有抽象方法,因此可以定义成一个普通类,如图4-26所示。
图4-26 继承抽象类
继承自抽象类的子类,如果想成为一个普通类,则子类必须实现父类所有的抽象方法;而如果子类继承自普通类,则子类可以有选择地决定需要重写的方法。
编写测试类Her Triangle1Test对子类Her Triangle1进行测试,如图4-27所示。
图4-27 Her Triangle1Test类
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。