完整word版零基础学JAVAJavaSE面向对象部分16面向对象高级04.docx
- 文档编号:29081216
- 上传时间:2023-07-20
- 格式:DOCX
- 页数:38
- 大小:427.10KB
完整word版零基础学JAVAJavaSE面向对象部分16面向对象高级04.docx
《完整word版零基础学JAVAJavaSE面向对象部分16面向对象高级04.docx》由会员分享,可在线阅读,更多相关《完整word版零基础学JAVAJavaSE面向对象部分16面向对象高级04.docx(38页珍藏版)》请在冰豆网上搜索。
完整word版零基础学JAVAJavaSE面向对象部分16面向对象高级04
上季内容回顾:
1、final关键字
•修饰类不能被继承
•修饰方法不能被覆写
•修饰的变量就是一个常量,全局常量(publicstaticfinal)
2、抽象类和接口
•抽象类:
只包含一个抽象方法的类,抽象方法只需声明而不需要实现,必须有子类
•接口:
只包含抽象方法和全局常量的类一一接口,也是必须有子类
在实际中一个类很少会去继承一个已经完全实现好的类,基本上都是继承抽象类和实现接口。
本季主要知识点:
1、对象的多态性
2、instanceof关键字
3、Object类对象的多态性
◎对$仃乂逻恥上MWf换
erxui向父炎对探转换(向上》
龟址英対象血子逆对徹杞挽向厂
金强引討力4孑史洞蔑=广子貴」址宝址滋
注意点:
为了清楚的阐述出概念,现在先使用普通类的继承关系。
向上转型:
classA
{
publicvoidfun1()
{
System.out.println("A类===>publicvoidfun1()");
}
publicvoidfun2()
{
〃fun2方法调用的是fun1方法
this.fun1();
}
}
classBextendsA
{
//覆写A类中的fun1()方法
publicvoidfun1()
{
System.out.println("B类===>publicvoidfun1()");
}
publicvoidfun3()
{
System.out.println("B类===>publicvoidfun3()");
}
}
publicclassDemo01
{
publicstaticvoidmain(Stringargs[])
{
Bb=newB();
Aa=newA();
b.fun1();
a.fun2();
b.fun3();
}
}
H:
\jaua\x)oi1>javacDeno01
H^^===5publicuoidl£nnlJ1
Fl类===>pufcliGvoidfunlO
B^=-=>puI)licvofunGO
E二Xjmu曰、dcj4〉
classA
{
publicvoidfun1()
{
System.out.println("A类===>publicvoidfun1()");
}
publicvoidfun2()
{
〃fun2方法调用的是fun1方法
this.fun1();
}
}
classBextendsA
{
//覆写A类中的fun1()方法
publicvoidfun1()
{
System.out.println("B类===>publicvoidfun1()");
}
publicvoidfun3()
{
System.out.println("B类===>publicvoidfun3()");
}
}
publicclassDemo02
{
publicstaticvoidmain(Stringargs[])
{
//声明一个父类对象
Aa=null;
//newB()是子类对象向父类对象转换
a=newB();
a.fun1();
}
}
现在我们来看下a.fun1()调用的是哪个类的方法哈
E:
\jau^i\Qo4>JauacDeno@2.Java
E:
\jaua\ooi1>jauaDcmcO2
B类■"冶ulilic;voidfunlO
E二Xjgujai\ou4〉.
classA
{
publicvoidfun1()
{
System.out.println("A类===>publicvoidfun1()");
}
publicvoidfun2()
{
〃fun2方法调用的是fun1方法
this.fun1();
}
}
classBextendsA
{
//覆写A类中的fun1()方法
publicvoidfun1()
{
System.out.println("B类===>publicvoidfun1()");
}
publicvoidfun3()
{
System.out.println("B类===>publicvoidfun3()");
}
}
publicclassDemo02
{
publicstaticvoidmain(Stringargs[])
{
//声明一个父类对象
Aa=null;
//newB()是子类对象向父类对象转换
//子类对象向父类对象转型之后,所调用的方法一定是被覆写过的方法a=newB();
a.fun1();
a.fun2();
}
E:
\jaua-\ot)4>JauacDen)oB2.Java
E:
\jauaXjoo4>J®u^Demo02B^===>pijihlicuoi B3^===>pul)licvoi E: \JauaXoc4> 向下转型: classA { publicvoidfun1() { System.out.println("A类===>publicvoidfun1()"); } publicvoidfun2() { 〃fun2方法调用的是fun1方法 this.fun1(); } } classBextendsA { //覆写A类中的fun1()方法 publicvoidfun1() { System.out.println("B类===>publicvoidfun1()"); } publicvoidfun3() { System.out.println("B类===>publicvoidfun3()"); } } publicclassDemo03 { publicstaticvoidmain(Stringargs[]) { //声明一个父类对象 Aa=null; //newB()是子类对象向父类对象转换 //子类对象向父类对象转型之后,所调用的方法一定是被覆写过的方法 现在我们来看下能否调用a.fun3()哈~ ncno03.jaua: 3b: 找不到荷号隠寻方法皿切 Kfi;类fi 4 1错误 E: \jauaXoo4> 程序提示找不到fun3()方法,A类中没有fun3()方法哈,如果我们一定要调用的话,我们就要使用向下转型哈~ classA { publicvoidfun1() { System.out.println("A类===>publicvoidfun1()"); } publicvoidfun2() { 〃fun2方法调用的是fun1方法 this.fun1(); } } classBextendsA { //覆写A类中的fun1()方法 publicvoidfun1() { System.out.println("B类===>publicvoidfun1()"); } publicvoidfun3() { System.out.println("B类===>publicvoidfun3()"); } publicclassDemo03 { publicstaticvoidmain(Stringargs[]) { //声明一个父类对象 Aa=null; //newB()是子类对象向父类对象转换 //子类对象向父类对象转型之后,所调用的方法一定是被覆写过的方法a=newB(); //可以进行向下转型,需要使用强制性手段哈〜 Bb=(B)a; b.fun3(); } } 验证下效果: E•\J*va\oo4>Deno03.java E;\Mua\o>jauaDeno03 B^===>publicuoid.fun3<> EiXjAua\oo4>_ 这就是对象向下转型哈〜 观察以下一种代码,检查下有没问题哈~: classA { publicvoidfun1() { System.out.println("A类===>publicvoidfun1()"); } publicvoidfun2() { 〃fun2方法调用的是funl方法 this.fun1(); } } classBextendsA { //现在我们不覆写A类中的fun1()方法 publicvoidfunX() { 程序找不到B类中被覆写的fun1()方法,所以去查找父类A中的fun1()方法了哈~ E: Xiaua>oo4>JauacDema04.java ! \j*ua\oo^Beno04publicvoidfunl<> E: xjaua\ot)4> classA { publicvoidfun1() { System.out.println("A类===>publicvoidfun1()"); } publicvoidfun2() { 〃fun2方法调用的是fun1方法 this.fun1(); } } classBextendsA { //覆写A类中的fun1()方法 publicvoidfun1() { System.out.println("B类===>publicvoidfun1()"); } publicvoidfun3() { E: >JauacDemo04.jdtuA E=\j 1类=M>pul)licvoidfunlO E: XjauaXoo4>_ 如果现在我们要调用fun3()方法呢? 现在使用向下转型可以吗 这样修改的话,我们看下有没问题哈,验证一下,发现编译时没有错误,但执行时却出现 ClassCastException错误了哈~ E: 口*1vacl>e-j: 昂va E: 7鼻啪事7v*PegH Enrvptioninthrafld''ftajauaaLangaC1a A PoiwMrJava! 11> E: 鼻1 在程序开发中有两大错误是比较常见的: •NullPointerException: 表示空指向异常,如果没有开辟堆内存空间,则出现此异常 •ClassCastException: 表示类转换异常,两个不相关的类的对象进行向下转型操作。 上面一个解释比较难理解哈,我们光看A类的话,我们不能知道A类有什么子类哈,但是如 果我们光看B类的话,我们可以看出B类是继承A类的话,所以得出了下面一个结论。 结论: 在进行向下转型之前,两个对象必然先发生向上转型关系,这样好建立起关系,否则两个 没有关系的对象是不能相互转型的。 对象多态性到底有那些用处呢? 如果不知道多态性的时候应该使用以下的方式编写代码,利用方法的重载完成。 classA } publicvoidfun2() { 〃fun2方法调用的是funl方法 this.fun1(); } } classBextendsA { //覆写A类中的fun1()方法 publicvoidfun1() { System.out.println("B类===>publicvoidfun1()"); } publicvoidfun3() { System.out.println("B类===>publicvoidfun3()"); } } classCextendsA { //覆写A类中的fun1()方法 publicvoidfun1() { System.out.println("C类===>publicvoidfun1()"); } publicvoidfun4() { System.out.println("C类===>publicvoidfun4()"); } } publicclassDemo05 { publicstaticvoidmain(Stringargs[]) { fun(newB()); fun(newC()); } //现在要求定义几个方法,可以接收父类A的子类对象 //如果不知道多态性的时候应该使用以下的方式编写代码 publicstaticvoidfun(Bb) { b.fun2(); } E! \jaua\oo4>jauAC.Jaua B^^==>fjublicvoidfunlOC^===>publicuoidfuni<> EJXjaua\oo4> 如果按此做法,就会面临一个很严重的问题: •如果现在A类有30个子类,则方法要重写30遍。 所以此时就可以利用对象的多态性完成,因为所有的子类对象都可以向父类对象转换。 现在我们就只留一个fun()方法,newB(),newC()都是A类的子类哈,所以现在不管调用 时传什么子类,都调用所传子类被覆写的fun1()方法哈~~~这就是对象多态性带来的好处, 谁被其实例化就具备这样的功能哈~如果父类设计的非常的完善,则方法中会非常的好写。 已弓》百DemoBG Xjava\oo4>j*UHaDeno06===>puhlicvoidfunl<>===>pui)licvoidfunl<) 7丑 要求: 如果传入的是B类的对象,则要求再调用fun3()方法,如果传入的是C类的对象,则要求 再调用fun4()方法。 问题: 如何去判断一个对象是否是某个类的实例呢? 这就需要instanceof关键字支持哈。 instanceof关键字 ◎instanceof^j 鸯对探irstdncyof 念f]*ainsiancmofE 令: : 处订狛圧? : BI坍d訂也ui反上『⑷佃詔 classA { publicvoidfun1() { System.out.println("A类===>publicvoidfun1()"); } publicvoidfun2() { 〃fun2方法调用的是fun1方法 this.fun1(); } } classBextendsA { } publicvoidfun3() { System.out.println("B类===>publicvoidfun3()"); { //覆写A类中的fun1()方法 publicvoidfun1() { System.out.println("C类===>publicvoidfun1()"); } publicvoidfun4() 我们来判断下对象b是否是A类的实例哈,我们分析下哈,子类B可以直接向父类A转型哈, 说明父类A可以接收子类B的实例,那两者必然有关系哈,我们验证一下,结果返回true 哈,证明对象b是A类的实例哈~ E=Beno07・力霾#目 E: DenoB? true E: '^ System.out.println("B类===>publicvoidfun3()"); } } classCextendsA { //覆写A类中的fun1()方法 publicvoidfun1() { System.out.println("C类===>publicvoidfun1()"); } publicvoidfun4() { System.out.println("C类===>publicvoidfun4()"); } } publicclassDemo07 { publicstaticvoidmain(Stringargs[]) { Bb=newB(); System.out.println(binstanceofA); System.out.println(binstanceofB); } } 对象b也肯定是B类的实例哈~ E: >jauacDenoB7.Java E: \java\oo^BemoO? true true classA { publicvoidfun1() { System.out.println("A类===>publicvoidfun1()"); } publicvoidfun2() { 〃fun2方法调用的是fun1方法 this.fun1(); } } 那相反对象a是B类的实例吗? 验证显示不是哈~说明不能向子类转换哈~ E: \jauJauacDemoB7.Ja.ua E;Xjaua\oo4>J*u^BemoB? true False E: \jauaXDo4> classA { publicvoidfun1() { System.out.println("A类===>publicvoidfun1()"); } publicvoidfun2() { 〃fun2方法调用的是fun1方法 this.fun1(); } } classBextendsA { //覆写A类中的fun1()方法 publicvoidfun1() { System.out.println("B类===>publicvoidfun1()"); } publicvoidfun3() { System.out.println("B类===>publicvoidfun3()"); } } classCextendsA { //覆写A类中的fun1()方法 publicvoidfun1() { System.out.println("C类===>publicvoidfun1()"); } publicvoidfun4() { System.out.println("C类===>publicvoidfun4()"); } } publicclassDemo08 { publicstaticvoidmain(Stringargs[]) { fun(newB()); System.out.println("#########################"); fun(newC()); } publicstaticvoidfun(Aa) { a.fun2(); 这就是instanceof关键字的作用哈~ Ez\jaua>^io4>Jav^cDeno68,jaua E: \jaua\o©4>jauaBenoSSB^-=->pul)lic B^;===>piit)licuciidfun3<> C^===>pul)licuoi F二Xjaium\ot)4〉 Instanceof的使用时机: 一般情况下都是在转型之前进行一下判断,这样就可以进行比较安全的转型操作。 Object类 ♦祈仃的爲郁必额缔匝门gect矣够U';equalS() ®t: 1jioString()//l'. Object 3 Iff训的爻那飙雨: lOt^ect矣 在Java中用户所编写的一切类都是一个类的子类,称为Object类。 实际上此类默认继承了Object类,以上代码等价于以下代码: 卜classStudentextendsObject Object类的作用: •如果一个好的类需要覆写Object类中的三个方法: |-publicStringtoString(): 对象输出时的操作 |-publicbooleanequals(Objectobj): 对象比较时的操作 |-publicinthashCode(): 返回该对象的哈希码值。 现在我们看下效果哈~ E: \j-ava\o.java E: \]鼻屮日\00攻》D&F1Q09Student(? ? 5? aef E: xJmueSo4 现在Student类是Object类的子类哈,那我们加上toString()看下效果 classStudent//extendsObject { privateStringname; privateintage; publicStudent(Stringname,intage) { this.name=name; this.age=age; } } publicclassDemo09 { publicstaticvoidmain(Stringargs[]) { System.out.println(newStudent("王乾",27).toString()); } } 我们发现和没加toString()之前的效果一样哈~ E: \jaua\oo4>javac E: DenoS'? Scudent0757aef E= 加和不加都是一样滴,那我们下面就覆写Object类的toString()方法哈~ classStudent//extendsObject { privateStringname; privateintage; publicStudent(Stringname,intage) { this.name=name; this.age=age; } publicStringtoString() { return"Michael"; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 完整 word 基础 JAVAJavaSE 面向 对象 部分 16 高级 04