您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 其它行业文档 > 第5章 深入理解Java语言
Java程序设计第五章深入理解Java语言多态的定义对象的多态性是指在基类中定义的属性或行为被派生类继承之后,可以具有不同的数据类型或表现出不同的行为。例如:“几何图形”的“绘图”方法,“椭圆”和“多边形”都是“几何图”的派生类,其“绘图”方法功能不同。多态的定义在Java中,多态性体现在两个方面:由方法重载实现的静态多态性(编译时多态)和方法重写实现的动态多态性(运行时多态)。1.静态多态在编译阶段,具体调用哪个被重载的方法,编译器会根据参数的不同来静态确定调用相应的方法。2.动态多态由于派生类继承了基类所有的属性(私有的除外),所以派生类对象可以作为基类对象使用。程序中凡是使用基类对象的地方,都可以用派生类对象来代替。一个对象可以通过引用派生类的实例来调用派生类的方法。静态多态静态多态在Java中的实现主要通过方法的重载来实现。在同一个类中,可以定义多个同名但参数不同的构造方法,这就是方法重载的体现。构造方法可以重载,一般的类方法也可以实现重载。动态多态动态多态是通过类与类之间方法的重写来实现。在基类中定义的方法可以有实现,也可以无实现(称为抽象方法),在派生类中对基类中的方法体进行重写的过程就是动态多态的实现。动态多态实现中涉及相关问题1、上溯造型2、动态邦定Student类对象Person类对象上转型对象(子类转换成父类)父类有的子类肯定有子类有的父类不一定有向上转换子类可以自动转换成父类classPerson{intname;intage;voidsayHello(){…}}classStudentextendsPerson{intdegree;voidstudy(){…}}Object父类对象和子类对象的转化原则(一)子类对象可以视为其父类的一个对象;而父类对象不能被当做其一个子类的对象。如果一个方法的形式参数定义的是父类对象,那么调用这个方法时,可以使用子类对象作为实际参数。上溯造型(Upcasting)对象对象的上转型对象继承或隐藏的成员变量继承或重写的方法新增的变量新增的方法把派生类型当做基本类型处理的过程,称为上溯造型。上转型对象会失去原对象的一些属性和功能Students=newStudent();Student类对象Person类对象ObjectPersonp=s;Objecto=s;classPerson{intname;intage;voidsayHello(){…}}classStudentextendsPerson{intdegree;voidstudy(){…}}Student类对象Person类对象ObjectStudent类对象Person类对象Object如果父类对象引用指向的实际是一个子类对象,那么父类对象的引用可以用强制类型转换转化成子类对象的引用。父类对象和子类对象的转化原则(二)Students=newStudent();Personp=s;Objecto=s;Students1=(Student)o;Student类对象Person类对象ObjectStudent类对象Person类对象Object例5-4classShape//基类{voiddraw(){System.out.println(Shapedrawing);}};classCircleextendsShape{voiddraw(){System.out.println(“DrawCircle”);}};classTriangleextendsShape{voiddraw(){System.out.println(“DrawTriangle”);};};classLineextendsShape{voiddraw(){System.out.println(“DrawLine”);};};classTestVirtualInvoke{staticvoiddoStuff(Shapes){s.draw();}publicstaticvoidmain(String[]args){Circlec=newCircle();Trianglet=newTriangle();Linel=newLine();doStuff(c);doStuff(t);doStuff(l);}}例5-4classShape//基类{voiddraw(){System.out.println(Shapedrawing);}};classCircleextendsShape{voiddraw(){System.out.println(“DrawCircle”);}//方法重载voidtest(){}};classTriangleextendsShape{voiddraw(){System.out.println(“DrawTriangle”);};//方法重载};classLineextendsShape{voiddraw(){System.out.println(“DrawLine”);};//方法重载};classTestVirtualInvoke{staticvoiddoStuff(Shapes){s.draw();}publicstaticvoidmain(String[]args){Circlec=newCircle();Trianglet=newTriangle();Linel=newLine();doStuff(c);}}((Circle)s).test();s.test();doStuff(t);动态类型确定Instanceof运算符经常在运行时判断所引用的对象的实际类型基本用法:变量instanceof类型如果变量与类型相同,或者是类型的子类型,则结果就是true;否则为falseclassTestVirtualInvoke{staticvoiddoStuff(Shapes){s.draw();}publicstaticvoidmain(String[]args){Circlec=newCircle();Trianglet=newTriangle();Linel=newLine();doStuff(c);}}If(sinstanceofCircle){((Circle)s).test();}doStuff(t);静态邦定与动态邦定静态邦定指在程序被编译时,编译器的工作是确保所编写的每一行编码都有意义。1、程序中所提到的变量是否都作了适当的说明。2、正在调用的所有函数(方法)也都作了适当的说明。动态邦定该语言特征把什么样的方法代码主体用于某个特定的方法调用这一决定推迟到程序的实际运行期。//MainApplicationPersonp;Students;Professorpr;……...…p.print(x,y);If(someruntimecondition)p=newStudent();elsep=newProfessor();ClassStudentextendsPerson{//detailomitted…publicvoidprint(inta,intb){……}pubiicvoidprint(inta){……}}ClassProfessorextendsPerson{//detailomitted…publicvoidprint(inta,intb){……}pubiicvoidprint(inta){……}}??//MainApplicationPersonp;Students;Professorpr;……...…p.print(x,y);If(someruntimecondition)p=newStudent();elsep=newProfessor();ClassStudentextendsPerson{//detailomitted…publicvoidprint(inta,intb){……}pubiicvoidprint(inta){……}}ClassProfessorextendsPerson{//detailomitted…publicvoidprint(inta,intb){……}pubiicvoidprint(inta){……}}classTestVirtualInvoke{staticvoiddoStuff(Shapes){s.draw();}publicstaticvoidmain(String[]args){Circlec=newCircle();Trianglet=newTriangle();Linel=newLine();doStuff(c);doStuff(t);doStuff(l);}}classShape//基类{voiddraw(){System.out.println(Shapedrawing);}};classCircleextendsShape{voiddraw(){System.out.println(“DrawCircle”);}}classTriangleextendsShape{voiddraw(){System.out.println(“DrawTriangle”);}}classLineextendsShape{voiddraw(){System.out.println(“DrawLine”);}}对象构造与初始化每个类都有一个构造方法,如果没有明确定义,系统会自动添加一个不带参数的构造方法构造方法可以重载,但不能继承。在构造方法中一定要调用本类或父类的构造方法(除object之外,因为object类没有父类)使用this调用本类的其它构造方法使用super调用父类的构造方法。Super指其直接父类的构造方法,不是指间接父类的构造方法既不用this,也不用super,则编译器会自动加上super(),即调用父类的不带参数的构造方法。例如:classA{A(inta){}}classBextendA{B(Strings){}//编译不通过}解决问题的方法:1、在B的构造方法中,加入调用父类的构造方法。2、在A中加入一个不带参数的构造方法3、去掉A中全部的构造方法,则系统会自动加入不带参数的默认构造方法classConstructCallThisAndSuper{publicstaticvoidmain(String[]args){Personp=newGraduate();}}classPerson{Stringname;intage;Person(){}Person(Stringname,intage){this.name=name;this.age=age;System.out.println(InPerson(String,int));}};classStudentextendsPerson{Stringschool;Student(){this(null,0,null);System.out.println(InStduent());}Student(Stringname,intage,Stringschool){super(name,age);this.school=school;System.out.println(InStduent(String,int,String));}};classGraduateextendsStudent{Graduate(){System.out.println(InGraduate());}};构造方法的执行过程对于一个复杂的对象,根据方法的执行过程遵照以下步骤(1)调用本类的构造或父类的构造方法。这个步骤会不断重复下去,直到抵达最深一层的派生类。(2)按声明顺序调用成员初始化模块。即执行域的初始化赋值。(3)执行构造方法中的各语句。
本文标题:第5章 深入理解Java语言
链接地址:https://www.777doc.com/doc-3768533 .html