第九讲面向对象编程:多态本章要点理解多态继承层次中对象间的关系抽象类接口引言通过上一章的学习,我们知道子类和超类之间是“is-a”的关系,即子类的对象也可以视为其超类的对象,而超类的对象却不能视为其子类的对象。既然子类的对象也可以视为其超类的对象,那么我们可不可以将子类对象的引用赋值给超类类型的变量呢?子类类型变量使用超类引用又是合法的嘛?引言Point3point=newPoint3(30,50);可以称为将超类对象的引用赋值给超类类型的变量或超类类型变量使用超类引用。Circle4circle=newCircle4(120,89,2.7);可以称为?Point3pointRef=circle;可以称为?子类对象调用超类方法变量所引用对象的类型用于确定实际响应方法调用的方法包含子类对象的引用的超类类型变量会调用子类方法变量可以调用的方法必须是该变量类型的成员子类类型变量使用超类引用将超类对象的引用赋值给子类类型的变量会产生编译错误,必须进行显式地强制类型转换。抽象类和抽象方法抽象方法:仅有定义,没有具体实现的方法抽象类:含有抽象方法的类定义一个抽象类,需要在类的定义前面加上“abstract”关键字定义一个抽象方法,需要在方法定义的前面加上“abstract”关键字一个类如果被定义为抽象类,它就不能被实例化,也就是说,不能有自己的对象抽象类的使用在Game,BoardGame,Chess实例中,Game类是作为所有游戏的总纲而出现的;Game类有Play()和GetRule()函数,但是这两个函数在总的Game类没有具体作用;作为总称的Game类,它的Play和GetRule函数完全是为底下具体的游戏子类而设计的,它本身并没有意义;因此,可以将这两个函数抽象化,作为一个总称,而不需要具体的内容。抽象类的使用抽象化的Game类:publicabstractclassGame{publicabstractvoidPlay();publicabstractStringGetRule();}可以定义抽象类的变量,但不能创建对象:GamemyGame;抽象类变量可以指向Game的子类的对象,再利用多态性来调用子类的Play或GetRule函数抽象类的使用抽象方法是没有具体实现的方法,它的作用就是被子类的相同函数覆盖,或通过多态性指向子类的相同函数通过抽象方法,可以定义一整套完整的方法功能,再派生出若干子类来实现不同的子类可以以不同的形式实现这些功能,但方法形式是完全一致的抽象类必须有子类,不然就没有意义抽象类的使用通过BoardGame类实现了一个抽象函数:abstractclassBoardGameextendsGame{publicStringGetRule(){return棋盘游戏是一种两人对弈的游戏。;}}BoardGame类没有实现Play函数,因为棋盘游戏依然是个抽象概念由于BoardGame没有实现Game类的全部抽象函数,因此BoardGame也必须定义为抽象类抽象类的使用Chess类覆盖GetRule函数,实现Play函数:classChessextendsBoardGame{publicStringGetRule(){StringBufferchessRule=newStringBuffer();chessRule=super.GetRule();chessRule+=国际象棋的规则如下:……;returnchessRule;}publicvoidPlay(){...}}Chess实现了全部抽象函数,它不是抽象类抽象类的使用抽象类中不仅仅有抽象方法(但通常包含抽象方法),也可以有普通的成员变量、构造方法和成员方法但如果一个类中有抽象方法,那么这个类必须定义为抽象类抽象类中可包含静态方法,但静态方法不能为抽象方法,可使用抽象类名.方法名来调用静态方法如果一个类继承了父类的几个抽象方法,但没有全部实现(如BoardGame类),那么这个类也必须定义为抽象类final方法和类final修饰成员变量,表明该变量不能在初始化后进行修改final修饰方法,表明该方法为最终方法,子类不能覆盖超类所声明的final方法声明为private的方法隐式地为final方法声明为static的方法隐式地为final方法final修饰类,表明该类是最终类,即该类不能被继承,不能为超类创建和使用接口声明接口使用关键字“interface”接口中一般只包含一组public抽象方法(且必须是公有抽象方法,但方法定义中publicabstract可省略),也可以包含public静态final数据为使用接口,必须指定实现该接口的类,并且该类必须按照接口所指定的方法特征来实现接口的各个方法如果一个类没有实现全部的接口方法,则它必须是抽象类,即必须以关键字abstract声明该类创建和使用接口Java不允许一个子类继承多个超类,却允许一个子类继承一个超类并实现多个接口,各个接口间以“,”分隔接口的另一个用途是:声明一组可用于多个类声明的常量抽象类与接口的比较抽象类(abstractmethod)接口(interface)都表示的是一种抽象的概念,是不能被实例化的在Java语言中表示的是一种继承关系,一个类只能使用一次继承关系一个类却可以实现多个interface可具有普通的成员变量成员变量必须是publicstaticfinal的可以有非abstarct的成员方法成员方法默认都是publicabstract设计理念上abstractclass表示的是is-a关系interface表示的是like-a关系