第5章 面向对象编程进阶.ppt
《第5章 面向对象编程进阶.ppt》由会员分享,可在线阅读,更多相关《第5章 面向对象编程进阶.ppt(74页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、LOGO第5章面向对象编程进阶主要内容主要内容类的继承类的继承1多态性多态性2静态初始化块静态初始化块3finalfinal修饰符修饰符4面向对象编程的三大特征:封装、继承继承和多态多态。主要内容5抽象类抽象类6接口接口7内部类内部类8匿名类匿名类5.1类的继承人是哺乳动物,因为人都具有哺乳动物的所有特征,但哺乳动物却不一定是人。哺乳动物类和人类之间就存在继承关系(IS-A)。mammalsdogscatshumanslionstigersleopards5.1类的继承继承是面向对象三大特征之一,也是实现软件复用的重要手段。继承的特点继承的特点通过继承,在已有类型基础之上进行扩充或改造,得到新
2、的数据类型。已有的类型称为父类或超类。得到的新数据类型,称为子类或派生类类的继承提高了程序代码的重用性和可扩充性,缩短了软件开发的周期。5.1类的继承继承的分类单继承-子类只能有一个直接父类多重继承-子类可以有多个直接父类类A类B类C类A类BJava不支持多重继承不支持多重继承5.1类的继承子类继承父类的语法格式修饰符class子类名extends父类名/子类代码部分例5.1编写程序示范子类继承父类的特点。publicclassAnimalpublicdoubleweight;publicvoideat()System.out.println(动物在吃东西);扩展(继承)5.1类的继承publ
3、icclassDogextendsAnimalpublicvoidsay()System.out.pringln(“狗叫:汪汪汪”);publicstaticvoidmain(Stringargs)Dogd=newDog();d.weight=150;d.eat();d.say();Dog类中没有定义weight属性和eat方法,是从父类Animal中继承下来,并且访问权限没有发生变化如果定义Java类时并未显示指定这个类的直接父类,则这个类默认扩展java.lang.Object类5.1类的继承 重写父类的方法重写父类的方法子类扩展父类-总是以父类为基础,额外增加新的属性和方法。但有一种情况
4、例外:子类需要重写父类的方法。例5.2子类重写父类的方法publicclassBirdpublicvoidfly()System.out.println(我在飞);5.1类的继承publicclassOstrichextendsBird/重写Bird类的fly方法-方法覆盖(方法覆盖(override)publicvoidfly()System.out.println(我只能在地上奔跑);publicstaticvoidmain(Stringargs)Ostrichos=newOstrich();os.fly();/调用的是Bird的fly还是Ostrich的fly?重写父类方法5.1类的继承
5、方法重写时要遵循的规则:“两同两小一大两同两小一大”规则规则“两同”即方法名相同,形参列表相同;“两小”指的是子类方法返回值类型应比父类方法返回值类型更小或相等,子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等;“一大”指的子类方法的访问权限应比父类方法更大或相等;覆盖方法和被覆盖方法要么都是类方法,要么都是实例方法,不能一个是类方法,一个是实例方法。5.1类的继承方法重写和方法重载的区别覆盖是子类和父类之间的关系;而重载是同一类内部多个方法之间的关系。覆盖一般是两个方法间的,而重载可能有多个重载的方法。覆盖的方法有相同的方法名和形参表;而重载的方法只能有相同的方法名,不能有相同
6、的形参表。覆盖时根据调用它的对象来区分方法;而重载是根据形参表来决定调用的是哪个方法。5.1类的继承父类实例的父类实例的super引用引用如果需要在子类方法中调用父类被覆盖的实例方法,可以用super作为调用者来调用父类被覆盖的实例方法。publicclassOstrichextendsBird/子类中原有的内容publicvoidcallOverridedMethod()super.fly();/输出“我在飞”在子类中想调用父类被覆盖的方法fly可以通过super关键字实现5.1类的继承注意:super是Java提供的一个关键字,它是直接父类对象的默认引用。正如this不能出现在static
7、修饰的方法中一样,super也不能出现在static的方法中如果子类定义了和父类同名的属性,也会发生子类属性覆盖父类属性的情形。子类的方法直接访问该属性时,都会访问到覆盖属性,无法访问父类被覆盖的属性-通过super来访问父类被覆盖的属性例5.3子类属性覆盖父类属性的实例。如果我们在某个方法中访问名为a的属性,但没有显示指定调用者,系统查找a的顺序为:查找该方法中是否有名为a的局部变量查找当前类中是否包含名为a的属性查找a的直接父类中是否包含名为a的属性,依次上溯a的父类,直到java.lang.Object类,如果最终不能找到名为a的属性,则系统出现编译错误。5.1类的继承调用父类构造方法调
8、用父类构造方法子类不会继承父类的构造方法,但有的时候子类构造方法里需要调用父类构造方法的初始化代码。例写出下面程序的执行结果。classBaseprotecteddoublesize;publicBase()size=0;System.out.println(“Base类无参构造”);publicBase(doubles)size=s;System.out.println(“Base类有参构造”);5.1类的继承publicclassSubextendsBaseprivateStringcolor;publicSub()color=“blue”;System.out.println(“Sub类
9、无参构造”);publicSub(Stringc)color=c;System.out.println(“Sub类有参构造”);publicstaticvoidmain(Stringargs)Subs1=newSub();Subs2=newSub(“red”);当通过子类构造方法创建子类对象时,默认的先执行父类不含参数的构造方法,再执行子类类构造方法。5.1类的继承 要在子类中显式调用直接父类带参数的构造方法,可通过super()调用来实现。例如,publicSub(doubles,Stringc)super(s);/调用Base类中带一个参数的构造方法color=c;System.out.p
10、rintln(“Sub类有参构造”);注意:super调用和this调用很像,区别在于super调用的是其父类的构造方法,而this调用的是同一个类中重载的构造方法。因此,使用super调用父类构造也必须出现在子类构造执行体的第一行,所以this调用和super调用不会同时出现不会同时出现。5.1类的继承子类构造方法调用父类构造方法分如下几种情况:子类构造方法执行体的第一行代码使用super显示调用父类构造方法,系统将根据super调用里传入的实参列表调用父类对应的构造方法。子类构造方法执行体的第一行代码使用this显示调用本类中重载的构造方法,系统将根据this调用里传入的实参列表调用本类另
11、一个构造方法。执行本类中另一个构造方法时即会调用父类的构造方法。子类构造方法执行体中既没有super调用,也没有this调用,系统将会在执行子类构造方法之前,隐式调用父类无参数的构造方法。例5.5构造方法的调用顺序。上机实践1.请按如下要求定义两个A和B:类A中定义一个int类型变量z(将其赋值为16)、一个char类型变量x(将其赋值为65)和一个方法myPrint(),该方法的功能是在屏幕上输出z的值和x的值。类B是类A的子类,其中定义了一个double类型的变量y(将其赋值为16.0)和String类型的对象s(将其赋值为javaprogram!),还定义了两个方法myPrint()和p
12、rintAll(),方法myPrint()的功能是在屏幕上输出y和s的值,方法printAll()的功能是分别调用父类和子类的myPrint()方法。编写应用程序,创建B类的对象b,调用printAll()方法用来显示z、x、y、s的值。上机实践2.阅读下面程序,回答问题。publicclassApublicstaticvoidmain(Stringargs)Aa=newA();A()System.out.println(“A”);A(inti)this();System.out.println(“AA”);classBextendsAB()super();System.out.println
13、(“B”);B(inti)super(i);System.out.println(“BB”);上机实践(1)程序输出的结果是什么?(2)若将main()方法中的语句改为:Bb=newB(),程序输出的结果是什么?(3)若将main()方法中的语句改为:Bb=newB(1),程序输出的结果是什么?5.2多态性多态机制是面向对象技术的精华之一,它是建立在继承基础之上的。所谓多态(polymorphism),子类的对象可以子类的对象可以代替父类的对象使用代替父类的对象使用。思想基础思想基础在类的继承中,子类在父类的基础上进行扩充和改造,父类拥有的成员子类中都有,因而可以认为子类比父类的功能强,或者说
14、子类的对象应该比父类的对象功能强,因而子类的对象应可以替代父类的对象被使用。例5.6多态性使用举例1源文件:Person.java、Student.java5.2多态性publicclassTestpublicstaticvoidmain(Stringargs)Personp=newStudent();/System.out.println(p.getInfo();变量p声明为父类Person的类型,但实际指向的却是子类Student类型的对象5.2多态性一个对象只能属于一种确定的数据类型,该类型自对象创建直至销毁不能改变。一个引用类型变量可能引用(指向)多种不同类型的对象既可以引用其声明类型
15、的对象,也可以引用也可以引用其声明类型的子类的对象其声明类型的子类的对象。Objecto=newString(“hello”);Personp1=newString(“hello”);Students=newPerson();Object是所有类的父类Person类和String类之间不存在继承关系子类变量不能引用父类对象注意:由于父类对象未包含子类中添加的成员,因而功能较弱,也就无法替代子类对象使用。p.getSchool()5.2多态性例5.7多态性使用举例2publicclassTestpublicvoidshow(Person p)System.out.println(p.getInf
16、o();publicstaticvoidmain(Stringargs)Personp=newPerson();Students=newStudent();Testt=newTest();t.show(p);t.show(s);方法的形参声明为Person类型调用时实参既可以是Person类型,也可以是其子类Student类型注意:show方法既可以处理Person类型的数据,也可以处理Student类型的数据,乃至未来定义的任何Person子类类型的数据,这样就不必为相关的每一种类型单独声明一个处理方法,提高了代码的通用性代码的通用性。5.2多态性在多态情况下,一个引用类型的变量如果声明为父
17、类的类型,但实际引用的是子类对象,则该变量就不能访问子类变量就不能访问子类中添加的属性和方法中添加的属性和方法。可是如果此时调用的是父类中声明过,且在子类中又重写过的方法子类中又重写过的方法,情况又将如何?例5.8多态性示例3name、pricesetName()getName()setPrice()getPrice()show()Book类authorsetAuthor()getAuthor()show()Novel类5.2多态性publicclassTestNovelpublicvoidprocess(Bookb)b.show();publicstaticvoidmain(Stringar
18、gs)TestNovelt=newTestNovel();Bookb=newBook();b.setName(“EnglishLanguage”);b.setPrice(34);t.process(b);/方法体中的方法体中的b.show()输出结果?输出结果?B既可引用Book类对象,又可引用Novel对象,则这时调用的到底是Book类中的show方法还是Novel类中的show方法?5.2多态性若增加如下代码:Noveln=newNovel();n.setName(“theGreatWall”);n.setPrice(46.7);n.setAuthor(“Zhangsan”);t.proc
19、ess(n);/方法体中的方法体中的b.show()的输出结果?的输出结果?结论:系统依据运行时对象的真正类型来确定具体调用哪一个方法父类对象调用父类中的show方法,子类对象调用子类中重写过的show方法。5.2多态性 对象造型对象造型在多态的情况下,由于对象以其父类的身份出现,对子对子类中新添加成员的访问受到限制类中新添加成员的访问受到限制,有时我们可能需要恢复一个对象的本来面目造型(Casting),以发挥其全部潜力。例5.9多态性示例4。PublicclassTestpublicvoidcast(Personp)/System.out.println(p.getSchool();非法S
20、tudentst=(Student)p;/造型造型System.out.println(st.getSchool();/正确在main方法中:Testt=newTest();Students=newStudent();s.setSchool(“THU”);t.cast(s);5.2多态性所谓的造型造型其实就是引用类型数据值之间的强制类型转换。注意:从子类到父类的类型转换可以自动进行;在多态的情况下,从父类到子类转换必须通过造型(强制类型转换)实现;无继承关系的引用类型间的转换是非法非法的。Stringstr=“hello,world”;Personp=(Person)str;5.2多态性特别强
21、调:从父类到子类的造型也不是都能成功也不是都能成功只有当对象的真正类型本就是子类类型,只是在多态的情况下,被一个声明为父类类型的变量所引用,才可以进行造型处理,即再恢复该对象的本来面目,而一个对象如果其真正类型就是父类类型,是不能被造型为子类类型的。例如,Personp1=newPerson();Studentstu=(Student)p1;/编译没没错,但运行出,但运行出错5.2多态性 instanceof运算符运算符再看例5.9中Test类的cast方法:publicvoidcast(Personp)/System.out.println(p.getSchool();非法Studentst
22、=(Student)p;/造型造型System.out.println(st.getSchool();/正确调用方法时如果实参是子类Student的对象,则造型是正确的,若实参是父类Person的对象,则造型失败!则造型失败!if(pinstanceofStudent)Studentst=(Student)p;st.getSchool();5.2多态性运算符instanceof用于检测一个对象的真正类型。格式:instanceof功能:如果instanceof操作符左侧的变量当前时刻所引用对象的真正类型是其右侧给出的类型、或是其子类,则整个表达式结果为true,否则结果为false。例5.10
23、多态性示例5。在Test类中的cast方法可改写为:publicvoidcast(Personp)if(pinstanceofGraduate).elseif(pinstanceofStudent)PersonStudentGraduate上机实践1.定义类A和类B如下:classAfloatvar=1.1f;floatmethod()returnvar;classBextendsAfloatvar=2.2;floatmethod()returnvar;(1)类A和类B是什么关系?(2)类A和类B中都定义了变量var和方法method(),这种现象称为什么?(3)若定义Aa=newA(),则a
24、.var和a.method()的值是多少?(4)若定义Aa=newB(),则a.var和a.method()的值是多少?(5)若定义Aa=newB(),Bb=(B)a,则b.var和b.method()的值是多少?5.3静态初始化块Java使用构造方法构造方法来对单个对象进行初始化操作。与构造方法作用非常类似的是初始化块初始化块,它也可以对对象进行初始化操作。使用初始化块使用初始化块初始化块是Java类里可以出现的第四种成员。语法格式:class类名修饰符/初始化块的可执行代码初始化块一个类里可以有多个初始化块;相同类型的初始化块之间有顺序,前面定义的初始化块先执行,后面定义的初始化块后执行。
25、只能是static,静态初始化块可以定义局部变量、调用其他对象的方法、使用分支、循环语句等5.3静态初始化块例5.7初始化块的使用。分析:当创建Java对象时,系统总是先调用该类里定义的初始化块;如果一个类里定义了两个普通初始化块,则前面定义的初始化块先执行,后面定义的初始化块后执行。初始化块虽然也是Java类里的一种成员,但它没有名字,也就没有标识,因此无法通过类、对象来调用初始化块;初始化块只能在创建对象时自动执行而且在执行构造方法之前执行。5.3静态初始化块例5.8初始化块的使用。注意:初始块和声明实例属性时所指定的初始值都是该实例的初始化代码,它们的执行顺序与源程序中排列顺序相同。初始
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第5章 面向对象编程进阶 面向 对象 编程 进阶
限制150内