YANGLIN@BNUITCJava程序设计第9章继承和多态学习目标理解类继承的概念以及父类和子类的关系理解super关键字掌握方法覆盖理解多态性、动态绑定和对象的强制类型转换理解数据字段和静态方法的隐藏掌握修饰符:protected、final了解ArrayList类Employee和ManagerEmployee+++namesalarybirthDate:String:double:Date+getDetails():StringpublicclassEmployee{publicStringname;publicdoublesalary;publicDatebirthDate;publicStringgetDetails(){...}}Manager++++namesalarybirthDatedepartment:String:double:Date:String+getDetails():StringpublicclassManager{publicStringname;publicdoublesalary;publicDatebirthDate;publicStringdepartment;publicStringgetDetails(){...}}继承publicclassEmployee{publicStringname;publicdoublesalary;publicDatebirthDate;publicStringgetDetails(){...}}publicclassManagerextendsEmployee{publicStringdepartment;}Employee+++namesalarybirthDate:String:double:Date+getDetails():StringManager+department:String父类和子类语法classClassNameextendsSuperclass{classbody}如果classC1extendsC2,则称C1为子类(subclass),C2为父类(superclass)。子类继承了父类中可访问的数据和方法,子类也可添加新的数据和方法,子类不继承父类的构造函数。一个类只能有一个直接父类。继承ManagerEmployeeEmployee的数据Employee的方法Employee的数据Manager的数据Employee的方法Manager的方法例几何对象类编写程序,父类GeometricObject,两个子类Circle和Rectangle。Example:v1/Circle.java,v1/Rectangle.java,v1/TestCircleRectangle.javaGeometricObject---colorfilleddateCreated:String:boolean:Date+++++getColor()setColor(Stringcolor)isFilled()setFilled(booleanfilled)getDateCreated():String:void:boolean:void:DateCircle-radius:double+++++++Circle()Circle(doubleradius)getRadius()setRadius(doubleradius)getArea()getPerimeter()getDiameter():double:void:double:double:doubleRectangle--widthheight:double:double++++++++Rectangle()Rectangle(doublewidth,doubleheight)getWidth()setWidth(doublewidth)getHeight()setHeight(doubleheight)getArea()getPerimeter():double:void:double:void:double:doublesuper关键字调用父类的构造函数super(parametersopt)调用父类的的构造函数。必须是子类构造函数的第一条语句。如果子类中没有显式地调用父类的构造函数,那么将自动调用父类不带参数的构造函数。父类的构造函数在子类构造函数之前执行。调用父类的成员super.datasuper.method(parameters)Example:ConstructorDemo.java方法覆盖如果子类重新定义了从父类中继承的实例方法,称为方法覆盖(methodoverride)。仅当方法是可访问的实例方法时,才能被覆盖,即私有方法不能被覆盖。静态方法不能被覆盖,如果静态方法在子类中重新定义,那么父类方法将被隐藏。一旦父类中的方法被覆盖,则不能从子类外部访问被覆盖的方法。在子类中可以使用super引用被覆盖的方法。Example:v2/Circle.java,v2/Rectangle.java,v2/TestCircleRectangle.javaOverrideTest.java覆盖与重载publicclassTest{publicstaticvoidmain(String[]args){Aa=newA();a.p(10);}}classB{publicvoidp(inti){}}classAextendsB{publicvoidp(inti){System.out.println(i);}}publicclassTest{publicstaticvoidmain(String[]args){Aa=newA();a.p(10);}}classB{publicvoidp(inti){}}classAextendsB{publicvoidp(doublei){System.out.println(i);}}Object类java.lang.Object类是所有类的父类。如果一个类在声明时没有指定父类,那么这个类的父类是Object类。equals方法:用于测试两个对象是否相等。Object类的默认实现是比较两个对象是否引用同一个对象。toString方法:返回代表这个对象的字符串。Object类的默认实现是返回由类名、@和hashCode组成。多态性、动态绑定当调用实例方法时,由Java虚拟机动态地决定所调用的方法,称为动态绑定(dynamicbinding)或为多态(polymorphism)。假定对象o是类C1的实例,C1是C2的子类,C2是C3的子类,…,Cn-1是Cn的子类。也就是说,Cn是最一般的类,C1是最特殊的类。在Java中,Cn是Object类。如果调用o的方法p,Java虚拟机按照C1、C2、…、Cn的顺序依次查找方法p的实现。一旦找到一个实现,将停止查找,并执行找到的第一个实现。CnCn-1…C2C1Object查找方法p的顺序对象o通用编程父类变量可以引用子类对象,针对父类对象设计的任何代码都可以应用于子类对象。多态性允许方法使用更通用的类作为参数类型。如果方法参数是父类,那么这个参数可以接受任何子类对象作为实参。当调用这对象的方法时,将动态绑定方法的实现。Example:poly/PolymorphismDemo.java类型转换类型转换(typecasting)可以将一个对象的类型转换成继承结构中的另一种类型。从子类到父类的转换是合法的,称为隐式转换。m(newStudent());Objecto=newStudent();m(o);从父类到子类必须显式转换,被转换的变量所指向的对象的类型必须是转换类或它的子类。Objecto=newStudent();Students=(Student)o;o所指向的对象必须是Student或Student子类的对象instanceof操作符可以用instanceof操作符判断一个对象是否是一个类的实例。表达式返回boolean值。语法referenceVariableinstanceofTypeName例强制类型转换编写程序,创建两个几何对象:圆和矩形。调用displayObject来显示结果。如果对象是圆,显示半径和面积如果对象是矩形,显示面积Example:v2/TestPolymorphismCasting.java隐藏数据字段和静态方法如果子类中声明的数据字段和静态方法与父类中的名称相同,那么父类中的将被隐藏(hide)。通过super关键字访问被隐藏的数据字段和静态方法。通过父类型的变量访问被隐藏的数据字段和静态方法。成员访问实例方法根据变量所引用的对象的实际类型进行访问。数据字段和静态方法根据变量的声明类型进行访问。Example:HideDemo.javaAx=newB();protected修饰符protected修饰符用于修饰数据和方法,可以被同一个包中的任何类或不同包中的子类访问。P2P1C1publicintxprotectedintyintzprivateintuC4C5C1c1=newC1()C2C3C1c1=newC1()C2中的代码可以访问x,y,zC3中的代码可以访问c1对象中的x,y,zC4中的代码可以访问x,yC5中的代码可以访问c1对象中的x类成员的访问控制符类的访问控制符public:类可以被任何包中的类访问无(package):只有同一个包中的类可以访问访问控制符成员修饰符同一个类相同包中的类子类不同包中的类public√√√√protected√√√无(package)√√private√final修饰符final数据:常量,数据初始化后不能再修改。final方法:最终方法,子类不能覆盖。final类:最终类,不能派生子类。String,StringBufferfinal局部变量:数据初始化后不能再修改。ArrayListjava.util.ArrayList类表示一个内部以数组存储的线性表。Example:TestArrayList.java,TestArrayListGeneric.java