java多态难点讲解.docx
- 文档编号:23348169
- 上传时间:2023-05-16
- 格式:DOCX
- 页数:23
- 大小:113.48KB
java多态难点讲解.docx
《java多态难点讲解.docx》由会员分享,可在线阅读,更多相关《java多态难点讲解.docx(23页珍藏版)》请在冰豆网上搜索。
java多态难点讲解
1多态概念
/*
多态:
同一个对象(事物),在不同时刻体现出来的不同状态。
举例:
猫是猫,猫是动物。
水(液体,固体,气态)。
多态的前提:
A:
要有继承关系。
B:
要有方法重写。
其实没有也是可以的,但是如果没有这个就没有意义。
动物d=new猫();
d.show();
动物d=new狗();
d.show();
C:
要有父类引用指向子类对象。
父f=new子();
用代码体现一下多态。
多态中的成员访问特点:
A:
成员变量
编译看左边,运行看左边。
B:
构造方法
创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。
C:
成员方法
编译看左边,运行看右边。
D:
静态方法
编译看左边,运行看左边。
(静态和类相关,算不上重写,所以,访问还是左边的)
由于成员方法存在方法重写,所以它运行看右边。
*/
classFu{
publicintnum=100;
publicvoidshow(){
System.out.println("showFu");
}
publicstaticvoidfunction(){
System.out.println("functionFu");
}
}
classZiextendsFu{
publicintnum=1000;
publicintnum2=200;
publicvoidshow(){
System.out.println("showZi");
}
publicvoidmethod(){
System.out.println("methodzi");
}
publicstaticvoidfunction(){
System.out.println("functionZi");
}
}
classDuoTaiDemo{
publicstaticvoidmain(String[]args){
//要有父类引用指向子类对象。
//父f=new子();
Fuf=newZi();
System.out.println(f.num);
//找不到符号
//System.out.println(f.num2);
f.show();
//找不到符号
//f.method();
f.function();
}
}
2多态好处
/*
多态的好处:
A:
提高了代码的维护性(继承保证)
B:
提高了代码的扩展性(由多态保证)
猫狗案例代码
*/
classAnimal{
publicvoideat(){
System.out.println("eat");
}
publicvoidsleep(){
System.out.println("sleep");
}
}
classDogextendsAnimal{
publicvoideat(){
System.out.println("狗吃肉");
}
publicvoidsleep(){
System.out.println("狗站着睡觉");
}
}
classCatextendsAnimal{
publicvoideat(){
System.out.println("猫吃鱼");
}
publicvoidsleep(){
System.out.println("猫趴着睡觉");
}
}
classPigextendsAnimal{
publicvoideat(){
System.out.println("猪吃白菜");
}
publicvoidsleep(){
System.out.println("猪侧着睡");
}
}
//针对动物操作的工具类
classAnimalTool{
privateAnimalTool(){}
/*
//调用猫的功能
publicstaticvoiduseCat(Catc){
c.eat();
c.sleep();
}
//调用狗的功能
publicstaticvoiduseDog(Dogd){
d.eat();
d.sleep();
}
//调用猪的功能
publicstaticvoidusePig(Pigp){
p.eat();
p.sleep();
}
*/
publicstaticvoiduseAnimal(Animala){
a.eat();
a.sleep();
}
}
classDuoTaiDemo2{
publicstaticvoidmain(String[]args){
//我喜欢猫,就养了一只
Catc=newCat();
c.eat();
c.sleep();
//我很喜欢猫,所以,又养了一只
Catc2=newCat();
c2.eat();
c2.sleep();
//我特别喜欢猫,又养了一只
Catc3=newCat();
c3.eat();
c3.sleep();
//...
System.out.println("--------------");
//问题来了,我养了很多只猫,每次创建对象是可以接受的
//但是呢?
调用方法,你不觉得很相似吗?
仅仅是对象名不一样。
//我们准备用方法改进
//调用方式改进版本
//useCat(c);
//useCat(c2);
//useCat(c3);
//AnimalTool.useCat(c);
//AnimalTool.useCat(c2);
//AnimalTool.useCat(c3);
AnimalTool.useAnimal(c);
AnimalTool.useAnimal(c2);
AnimalTool.useAnimal(c3);
System.out.println("--------------");
//我喜欢狗
Dogd=newDog();
Dogd2=newDog();
Dogd3=newDog();
//AnimalTool.useDog(d);
//AnimalTool.useDog(d2);
//AnimalTool.useDog(d3);
AnimalTool.useAnimal(d);
AnimalTool.useAnimal(d2);
AnimalTool.useAnimal(d3);
System.out.println("--------------");
//我喜欢宠物猪
//定义一个猪类,它要继承自动物,提供两个方法,并且还得在工具类中添加该类方法调用
Pigp=newPig();
Pigp2=newPig();
Pigp3=newPig();
//AnimalTool.usePig(p);
//AnimalTool.usePig(p2);
//AnimalTool.usePig(p3);
AnimalTool.useAnimal(p);
AnimalTool.useAnimal(p2);
AnimalTool.useAnimal(p3);
System.out.println("--------------");
//我喜欢宠物狼,老虎,豹子...
//定义对应的类,继承自动物,提供对应的方法重写,并在工具类添加方法调用
//前面几个必须写,我是没有意见的
//但是,工具类每次都改,麻烦不
//我就想,你能不能不改了
//太简单:
把所有的动物都写上。
问题是名字是什么呢?
到底哪些需要被加入呢?
//改用另一种解决方案。
}
/*
//调用猫的功能
publicstaticvoiduseCat(Catc){
c.eat();
c.sleep();
}
//调用狗的功能
publicstaticvoiduseDog(Dogd){
d.eat();
d.sleep();
}
*/
}
3多态坏处
/*
多态的弊端:
不能使用子类的特有功能。
*/
classFu{
publicvoidshow(){
System.out.println("showfu");
}
}
classZiextendsFu{
publicvoidshow(){
System.out.println("showzi");
}
publicvoidmethod(){
System.out.println("methodzi");
}
}
classDuoTaiDemo3{
publicstaticvoidmain(String[]args){
//测试
Fuf=newZi();
f.show();
f.method();
}
}
/*
多态的弊端:
不能使用子类的特有功能。
我就想使用子类的特有功能?
行不行?
行。
怎么用呢?
A:
创建子类对象调用方法即可。
(可以,但是很多时候不合理。
而且,太占内存了)
B:
把父类的引用强制转换为子类的引用。
(向下转型)
对象间的转型问题:
向上转型:
Fuf=newZi();
向下转型:
Ziz=(Zi)f;//要求该f必须是能够转换为Zi的。
*/
classFu{
publicvoidshow(){
System.out.println("showfu");
}
}
classZiextendsFu{
publicvoidshow(){
System.out.println("showzi");
}
publicvoidmethod(){
System.out.println("methodzi");
}
}
classDuoTaiDemo4{
publicstaticvoidmain(String[]args){
//测试
Fuf=newZi();
f.show();
//f.method();
//创建子类对象
//Ziz=newZi();
//z.show();
//z.method();
//你能够把子的对象赋值给父亲,那么我能不能把父的引用赋值给子的引用呢?
//如果可以,但是如下
Ziz=(Zi)f;
z.show();
z.method();
}
}
5类型转换异常
/*
ClassCastException:
类型转换异常
一般在多态的向下转型中容易出现
*/
classAnimal{
publicvoideat(){}
}
classDogextendsAnimal{
publicvoideat(){}
publicvoidlookDoor(){
}
}
classCatextendsAnimal{
publicvoideat(){
}
publicvoidplayGame(){
}
}
classDuoTaiDemo5{
publicstaticvoidmain(String[]args){
//内存中的是狗
Animala=newDog();
Dogd=(Dog)a;
//内存中是猫
a=newCat();
Catc=(Cat)a;
//内存中是猫
Dogdd=(Dog)a;//ClassCastException
}
}
6多态猫狗案例
/*
多态练习:
猫狗案例
*/
classAnimal{
publicvoideat(){
System.out.println("吃饭");
}
}
classDogextendsAnimal{
publicvoideat(){
System.out.println("狗吃肉");
}
publicvoidlookDoor(){
System.out.println("狗看门");
}
}
classCatextendsAnimal{
publicvoideat(){
System.out.println("猫吃鱼");
}
publicvoidplayGame(){
System.out.println("猫捉迷藏");
}
}
classDuoTaiTest{
publicstaticvoidmain(String[]args){
//定义为狗
Animala=newDog();
a.eat();
System.out.println("--------------");
//还原成狗
Dogd=(Dog)a;
d.eat();
d.lookDoor();
System.out.println("--------------");
//变成猫
a=newCat();
a.eat();
System.out.println("--------------");
//还原成猫
Catc=(Cat)a;
c.eat();
c.playGame();
System.out.println("--------------");
//演示错误的内容
//Dogdd=newAnimal();
//Dogddd=newCat();
//ClassCastException
//Dogdd=(Dog)a;
}
}
7多态饮食案例
/*
不同地方饮食文化不同的案例
*/
classPerson{
publicvoideat(){
System.out.println("吃饭");
}
}
classSouthPersonextendsPerson{
publicvoideat(){
System.out.println("炒菜,吃米饭");
}
publicvoidjingShang(){
System.out.println("经商");
}
}
classNorthPersonextendsPerson{
publicvoideat(){
System.out.println("炖菜,吃馒头");
}
publicvoidyanJiu(){
System.out.println("研究");
}
}
classDuoTaiTest2{
publicstaticvoidmain(String[]args){
//测试
//南方人
Personp=newSouthPerson();
p.eat();
System.out.println("-------------");
SouthPersonsp=(SouthPerson)p;
sp.eat();
sp.jingShang();
System.out.println("-------------");
//北方人
p=newNorthPerson();
p.eat();
System.out.println("-------------");
NorthPersonnp=(NorthPerson)p;
np.eat();
np.yanJiu();
}
}
8多态测试
/*
看程序写结果:
先判断有没有问题,如果没有,写出结果
*/
classFu{
publicvoidshow(){
System.out.println("fushow");
}
}
classZiextendsFu{
publicvoidshow(){
System.out.println("zishow");
}
publicvoidmethod(){
System.out.println("zimethod");
}
}
classDuoTaiTest3{
publicstaticvoidmain(String[]args){
Fuf=newZi();
//找不到符号
//f.method();
f.show();
}
}
9多态成员访问特点
/*
看程序写结果:
先判断有没有问题,如果没有,写出结果
多态的成员访问特点:
方法:
编译看左边,运行看右边。
继承的时候:
子类中有和父类中一样的方法,叫重写。
子类中没有父亲中出现过的方法,方法就被继承过来了。
*/
classA{
publicvoidshow(){
show2();
}
publicvoidshow2(){
System.out.println("我");
}
}
classBextendsA{
/*
publicvoidshow(){
show2();
}
*/
publicvoidshow2(){
System.out.println("爱");
}
}
classCextendsB{
publicvoidshow(){
super.show();
}
publicvoidshow2(){
System.out.println("你");
}
}
publicclassDuoTaiTest4{
publicstaticvoidmain(String[]args){
Aa=newB();
a.show();
Bb=newC();
b.show();
}
}
10多态继承与转型
多态的问题理解:
class孔子爹{
publicintage=40;
publicvoidteach(){
System.out.println("讲解JavaSE");
}
}
class孔子extends孔子爹{
publicintage=20;
publicvoidteach(){
System.out.println("讲解论语");
}
publicvoidplayGame(){
System.out.println("英雄联盟");
}
}
//Java培训特别火,很多人来请孔子爹去讲课,这一天孔子爹被请走了
//但是还有人来请,就剩孔子在家,价格还挺高。
孔子一想,我是不是可以考虑去呢?
//然后就穿上爹的衣服,带上爹的眼睛,粘上爹的胡子。
就开始装爹
//向上转型
孔子爹k爹=new孔子();
//到人家那里去了
System.out.println(k爹.age);//40
k爹.teach();//讲解论语
//k爹.playGame();//这是儿子才能做的
//讲完了,下班回家了
//脱下爹的装备,换上自己的装备
//向下转型
孔子k=(孔子)k爹;
System.out.println(k.age);//20
k.teach();//讲解论语
k.playGame();//英雄联盟
11多态继承中内存的问题
2多态中对象变化内存图解
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- java 难点 讲解