第6章继承与多态.

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

L/O/G/OJava程序设计第6章继承与多态6.1继承6.2多态性6.3几个特殊类6.4访问控制修饰符6.5final修饰符的使用6.6对象引用转换继承的概念继承性是指一个类(子类)可以从另一个类(父类)继承它的状态和行为。父类:实际上是所有子类的公共域和公共方法的集合.子类:父类的特殊化,是对公共域和方法在功能、内涵方面的扩展和延伸,祖先类的所有成员均将成为子类拥有的“财富”Java中所有的类都直接或间接的继承java.lang.Object类。Java中不支持多重继承,属于单一继承,每个类只有一个父类。publicclassPerson{Stringname;//姓名Stringsex;//性别Stringid;//身份证号Stringjiguan;//籍贯}publicclassStudent{Stringname;//姓名Stringsex;//性别Stringid;//身份证号Stringjiguan;//籍贯Stringsno;//学号...}前四个属性,在Person类中有定义。6.1.1子类的创建在类的声明中,可以通过使用关键字extends来显式地指明其父类。语法格式为:[修饰符]class子类名extends父类名修饰符:可选,用于指定类的访问权限,可选值为public、abstract和final。子类名:必选,用于指定子类的名称,类名必须是合法的Java标识符。一般情况下,要求首字母大写。extends父类名:必选,用于指定要定义的子类继承于哪个父类。6.1.1子类的创建classStudentextendsPerson{Stringsno;//学号//其他……}只有sno属性是新加入的,其它属性在Person类中均存在6.1.2继承关系中构造方法的作用父类的那些属性值,让父类构造!---各司其责实例化子类时,会先初始化父类。即:先执行父类的构造方法,再执行子类构造方法。初始化父类时,默认调用父类的无参构造方法。如果父类中没有定义无参构造方法,编译器将报错。可以在子类中使用关键字super来调用父类的构造方法,但super调用语句必须是子类构造方法中的第一个可执行语句;以下程序在编译时将出错,为什么?classparent{Stringmy;publicparent(Stringx){my=x;}}publicclasssubclassextendsparent{}parent类没有无参构造方法。所以,类设计通常要提供无参构造方法【例6-1】类的继承中构造方法的调用测试classPerson{...publicPerson(){}publicPerson(Stringn,Strings,Stringi,Stringj){name=n;sex=s;id=i;jiguan=j;}}【例6-1】续publicclassStudentextendsPerson{publicStudent(){}publicStudent(Stringname,Stringsex,Stringid,Stringjiguan,Stringsno){super(name,sex,id,jiguan);this.sno=sno;}}【注意】使用this查找匹配的方法时首先在本类查找,找不到时再到其父类和祖先类查找;使用super查找匹配方法时,首先到直接父类查找,如果不存在,则继续到其祖先类逐级往高层查找。用super调用父类成员Super关键字子类中包含一个父类对象的引用super,可以通过super关键字实现对父类成员的访问。访问父类被隐藏的成员变量:super.variable调用父类中被重写的方法:super.method([paramlist])调用父类的构造方法super();继承的使用原则子类可以继承父类中所有可被子类访问的成员变量和成员方法,但必须遵循以下原则:1.子类能够继承父类中被声明为public和protected的成员变量和成员方法,但不能继承被声明为private的成员变量和成员方法;2.子类能够继承在同一个包中的由默认修饰符修饰的成员变量和成员方法;继承的使用原则3.如果子类声明了一个与父类的成员变量同名的成员变量,则子类不能继承父类的成员变量,此时称子类的成员变量隐藏了父类的成员变量;可以通过super关键字调用父类的成员变量4.如果子类声明了一个与父类的成员方法同名的成员方法,则子类不能继承父类的成员方法,此时称子类的成员方法覆盖了父类的成员方法。可以通过super关键字调用父类的成员方法6.2多态性多态是指一个程序中同名的方法共存的情况,可以理解为一个方法,多种实现。Java中,多态性体现在两个方面:(1)方法重载(overload):实现了静态多态性(编译时多态)编译时多态:在编译阶段,编译器根据参数的不同来静态确定调用响应的方法,即前期绑定。(2)方法重写(override):实现了动态多态性(运行时多态)。运行时多态:父类对象的引用可以指向一个子类对象,可以利用这一点,在运行时,根据实际对象的类型决定调用不同的方法。即后期绑定,或动态绑定、运行时绑定方法重载是指在同一个类中多个方法享有相同的名字,但是这些方法的参数必须不同,或者是参数的个数不同,或者是参数类型不同。返回类型不能用来区分重载的方法,编译器报错。例题Overload.java6.2.1方法的重载方法调用的匹配处理原则首先按“精确匹配”原则去查找匹配方法,如果找不到,则按“自动类型转换匹配”原则去查找能匹配的方法。所谓“精确匹配”就是实参和形参类型完全一致。所谓“自动转换匹配”是指虽然实参和形参类型不同,但能将实参的数据按自动转换原则赋值给形参。【思考】如果将test(intx)方法注释掉,则调用test(5)如何?3个方法中,只将test(doublex)方法注释掉,程序能编译通过吗?publicclassOverload{//voidtest(intx){System.out.println(int:+x);}voidtest(longx){System.out.println(long:+x);}voidtest(doublex){System.out.println(double:+x);}publicstaticvoidmain(String[]args){Overloada1=newOverload();a1.test(5.0);a1.test(5);}}6.2.2方法的覆盖通过继承,子类将获得父类的非私有方法;在子类中对父类定义的方法重新定义,此时将会产生方法的覆盖。子类在定义父类方法时,要保持与父类方法完全相同的方法头部声明,即相同的方法名,参数列表,返回值类型一般也要求一样。6.2.2方法的覆盖以下类Sub定义的方法中,方法覆盖如何?classSubextendsOverload{voidtest(intx){System.out.println(inSub.test(int):+x);}voidtest(Stringx,inty){System.out.println(inSub.test(String,int):+x+,+y);}}【思考】通过子类Sub的对象可调用多少test方法?publicclassOverload{voidtest(intx)…voidtest(longx)…voidtest(doublex)…}注意:方法覆盖的问题方法声明完全相同才会产生方法覆盖或重写(override);返回类型通常也要一致;只有返回类型为引用类型时,允许子类方法的返回类型是父类方法返回类型的子类型。其他情形导致类型不一致时编译将指示错误。覆盖不能改变方法的静态与非静态属性。子类中不能将父类非静态方法定义为静态方法,反之也一样。不允许子类方法的访问修饰符比父类有更多的限制。例如:子类不能将父类的public方法定义为protected方法。但可以将父类的private方法在子类中重新定义为public方法.final方法不能被覆盖。6.2.3访问继承的成员(1)子类中可以像访问自己的成员一样访问父类的public和protected成员,但不能访问private和不同包的default成员。如果子类中定义了与父类同名的属性,在子类中将隐藏来自父类的同名属性变量。(2)通过子类的引用变量访问自己的对象时,无论属性和方法优先考虑子类新定义的。自己类中没有的再到父类找。6.6.1对象引用赋值转换假设B类是A类的子类或间接子类,当用子类B创建一个对象b,并把这个对象的引用放到A类的对象a中时,对象a就是子类对象b的上转型对象。也就是说将子类对象赋值给父类的引用。ClassA{}ClassBextendsA{}Aa;Bb=newB();a=b;//a为子类对象b的上转型对象6.6.1对象引用赋值转换上转型对象访问权限继承自父类的成员变量(包含被隐藏的父类的成员变量)能访问子类新增的成员变量不能访问子类继承的父类的方法(包含重写的继承自父类的方法)能访问子类新增加的方法不能访问向上转型【例】创建动物类,在该类中定义一个cry()动物大叫的方法;并创建两个子类:狗和猫,在子类中重写cry()方法。在Zoo类中定义hunt()捕捉方法,该方法接收动物类做方法的参数,并调用参数的cry()方法模拟动物在遭到捕捉时的反应。测试写运行结果classTest5{intk=8;publicvoiddoSome(){System.out.println(k1=+k);}}classSubextendsTest5{intk=66;publicvoiddoSome(){k=k-2;System.out.println(k2=+k);}publicstaticvoidmain(Stringargs[]){Test5obj=newSub();obj.doSome();System.out.println(k3=+obj.k);}}k2=64k3=8运行结果思考:(1)将obj定义为子类引用变量如何?(2)将子类的dosom()方法删除又如何?写运行结果classexSuper{publicvoidfunc(Stringp,Strings){System.out.println(p);}}publicclassexampleextendsexSuper{publicvoidfunc(Stringp,Strings){System.out.println(p+:+s);}staticpublicvoidmain(Stringarg[]){exSupere1=newexSuper();e1.func(hello1,hi1);exSupere2=newexample();e2.func(hello2,hi2);}}hello1hello2:hi2运行结果6.6.2对象引用强制转换将父类引用赋值给子类变量时要进行强制类型转换;例如:Dogd=(Dog)newAnimal();强制转换在编译时总是认可的,但运行时的情况取决于对象的值。例如:Objectm=newString(“123”);//上转型对象Stringy=m;//出错,必须强制类型转换Stringy=(String)m;//正确,编译允许且运行没问题Integerp=(Integer)m;//强制转换,编译允许,但运行时出错写运行结果publicclassTest6{staticvoidm(doublex){System.out.println(m(double):+x);}staticvoidm(Objectobj){System.out.println(m(Object):+obj);}publicstaticvoidmain(Stringargs[]){m(hello);m(5);}}m(Object):hellom(double):5.0运行结果问

1 / 31
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功