1.抽象类

1.抽象类

(1)抽象类的引出

在代码16.8中,Bird类和Ostrich类有继承关系,Ostrich类中重写了父类Bird中的fly()方法,那么,Ostrich类的对象调用的fly()方法就是Ostrich类中自己定义的fly()方法。

接下来,有另外一种情况:对于Bird(鸟)和Plane(飞机),它们没有直接的继承关系,但是它们是有共通之处的。

【代码16.25】Bird(鸟)和Plane(飞机)的定义

抽象类-1

抽象类-2

在代码16.25中,Bird和Plane是不会有父子关系的,也不会有兄弟关系。但是他们有共通的特征:都有id和name属性;都有相同的introduce()方法;都有fly()方法(但是实现体不同)。

现在我们把Bird和Plane中相同的特征抽取出来,使其成为Flyer(飞行器)父类,Bird和Plane都继承Flyer,因为鸟和飞机都会飞,只是飞的方式不同。

Flyer(飞行器)是抽取所有具体的飞行器特征,而每种具体飞行器的fly()的实现体是不同的,所以Flyer的fly()是写不出实现体的,Flyer是个抽象类,它规定了所有具体的飞行器应该具有的特征。

【代码16.26】Flyer抽象类、Bird(鸟)类、Plane(飞机)类的定义

运行结果:

id:1,name:老鹰

鸟儿:我展翅就可以高飞。

****************

id:2,name:波音747

飞机:滑行-起飞-飞行-降落-着陆-滑行。

在代码16.26第33行的Test16_26类中,go()方法接收的参数是父类Flyer类型,那么在调用的时候就可以接受Bird或者Plane的子类对象。在执行的时候,根据传入的具体类型,动态绑定对应类的fly()方法。所以,同样的go()方法调用不同的对象时,其运行结果不同。

如果又有了新的具体飞行器〔如Cloud云它有自己的fly()实现〕,只需要定义Cloud类,继承自Flye类,实现fly()方法。在Test16_26类中,整个程序结构不需要改变,为go()方法传入Cloud类的对象即可。可以理解为在程序的主干不改变的情况下,可以替换传入的对象类型(Bird、Plane、Cloud),这样提高了程序的可扩展性和可维护性。

(2)抽象类的语法规定

抽象类用来给出一组子类的设计模板,子类可以对父类进行扩展,但必须实现父类中所有的抽象方法,这避免了子类设计的随意性。

抽象类的意义

抽象类的语法规定:

①用abstract修饰的类就是抽象类,抽象类是不能被实例化的。

②抽象方法用abstract修饰,没有方法体;包含抽象方法的类一定是抽象类。

③abstract不能与private、static、final并列修饰一个方法。

抽象类定义的语法格式如下:

抽象类给类定义“模板”,将类进行类型的划分,是用来继承的。

如果继承了抽象类,就必须实现父类中所有的抽象方法,否则,本类也成为抽象类。