how2j.cn


工具版本兼容问题
操作符的多态
+ 可以作为算数运算,也可以作为字符串连接

类的多态
父类引用指向子类对象

本视频是解读性视频,所以希望您已经看过了本知识点的内容,并且编写了相应的代码之后,带着疑问来观看,这样收获才多。 不建议一开始就观看视频



5分32秒
本视频采用html5方式播放,如无法正常播放,请将浏览器升级至最新版本,推荐火狐,chrome,360浏览器 如果装有迅雷,播放视频呈现直接下载状态,请调整 迅雷系统设置-基本设置-启动-监视全部浏览器 (去掉这个选项)



示例 1 : 操作符的多态   
示例 2 : 观察类的多态现象   
示例 3 : 类的多态条件   
示例 4 : 类的多态-不使用多态   
示例 5 : 类的多态-使用多态   
示例 6 : 练习-多态   
示例 7 : 答案-多态   

示例 1 :

操作符的多态

同一个操作符在不同情境下,具备不同的作用
如果+号两侧都是整型,那么+代表 数字相加
如果+号两侧,任意一个是字符串,那么+代表字符串连接
package charactor; public class Hero { public String name; protected float hp; public static void main(String[] args) { int i = 5; int j = 6; int k = i+j; //如果+号两侧都是整型,那么+代表 数字相加 System.out.println(k); int a = 5; String b = "5"; String c = a+b; //如果+号两侧,任意一个是字符串,那么+代表字符串连接 System.out.println(c); } }
示例 2 :

观察类的多态现象

观察类的多态现象:
1. i1和i2都是Item类型
2. 都调用effect方法
3. 输出不同的结果

多态: 都是同一个类型,调用同一个方法,却能呈现不同的状态
观察类的多态现象
package property; public class Item { String name; int price; public void buy(){ System.out.println("购买"); } public void effect() { System.out.println("物品使用后,可以有效果 "); } public static void main(String[] args) { Item i1= new LifePotion(); Item i2 = new MagicPotion(); System.out.print("i1 是Item类型,执行effect打印:"); i1.effect(); System.out.print("i2也是Item类型,执行effect打印:"); i2.effect(); } }
package property; public class LifePotion extends Item { public void effect(){ System.out.println("血瓶使用后,可以回血"); } }
package property; public class MagicPotion extends Item{ public void effect(){ System.out.println("蓝瓶使用后,可以回魔法"); } }
示例 3 :

类的多态条件

要实现类的多态,需要如下条件
1. 父类(接口)引用指向子类对象
2. 调用的方法有重写
那么多态有什么作用呢? 通过比较不使用多态使用多态来进一步了解
示例 4 :

类的多态-不使用多态

如果不使用多态
假设英雄要使用血瓶和魔瓶,就需要为Hero设计两个方法
useLifePotion
useMagicPotion


除了血瓶和魔瓶还有很多种物品,那么就需要设计很多很多个方法,比如
usePurityPotion 净化药水
useGuard 守卫
useInvisiblePotion 使用隐形药水
等等等等
package charactor; import property.LifePotion; import property.MagicPotion; public class Hero { public String name; protected float hp; public void useLifePotion(LifePotion lp){ lp.effect(); } public void useMagicPotion(MagicPotion mp){ mp.effect(); } public static void main(String[] args) { Hero garen = new Hero(); garen.name = "盖伦"; LifePotion lp =new LifePotion(); MagicPotion mp =new MagicPotion(); garen.useLifePotion(lp); garen.useMagicPotion(mp); } }
示例 5 :

类的多态-使用多态

如果物品的种类特别多,那么就需要设计很多的方法
比如useArmor,useWeapon等等

这个时候采用多态来解决这个问题
设计一个方法叫做useItem,其参数类型是Item
如果是使用血瓶,调用该方法
如果是使用魔瓶,还是调用该方法
无论英雄要使用什么样的物品,只需要一个方法即可
package charactor; import property.Item; import property.LifePotion; import property.MagicPotion; public class Hero { public String name; protected float hp; public void useItem(Item i){ i.effect(); } public static void main(String[] args) { Hero garen = new Hero(); garen.name = "盖伦"; LifePotion lp =new LifePotion(); MagicPotion mp =new MagicPotion(); garen.useItem(lp); garen.useItem(mp); } }
示例 6 :

练习-多态

Or  姿势不对,事倍功半! 点击查看做练习的正确姿势

immortal是不朽的,不死的意思
mortal就是终有一死的,凡人的意思

1. 设计一个接口
接口叫做Mortal,其中有一个方法叫做die
2. 实现接口
分别让ADHero,APHero,ADAPHero这三个类,实现Mortal接口,不同的类实现die方法的时候,都打印出不一样的字符串
3. 为Hero类,添加一个方法,在这个方法中调用 m的die方法。

public void kill(Mortal m)

4. 在主方法中
首先实例化出一个Hero对象:盖伦
然后实例化出3个对象,分别是ADHero,APHero,ADAPHero的实例
然后让盖伦 kill 这3个对象
示例 7 :

答案-多态

在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
本视频是解读性视频,所以希望您已经看过了本答案的内容,带着疑问来观看,这样收获才多。 不建议一开始就观看视频

3分49秒 本视频采用html5方式播放,如无法正常播放,请将浏览器升级至最新版本,推荐火狐,chrome,360浏览器 如果装有迅雷,播放视频呈现直接下载状态,请调整 迅雷系统设置-基本设置-启动-监视全部浏览器 (去掉这个选项)


答案-多态
package charactor; public interface Mortal { public void die(); }
package charactor; public class ADHero extends Hero implements AD ,Mortal{ @Override public void physicAttack() { } @Override public void die() { System.out.println(name+ " 这个物理英雄挂了"); } }
package charactor; public class APHero extends Hero implements AP,Mortal { public void magicAttack() { } @Override public void die() { System.out.println(name+ " 这个魔法英雄挂了"); } }
package charactor; public class ADAPHero extends Hero implements AD,AP,Mortal{ @Override public void magicAttack() { // TODO Auto-generated method stub } @Override public void physicAttack() { // TODO Auto-generated method stub } @Override public void die() { System.out.println(name+ " 这个混合英雄挂了"); } }
package charactor; public class Hero { public String name; protected float hp; public void kill(Mortal m){ System.out.println(name + " 放了一个大招" ); m.die(); } public static void main(String[] args) { Hero h =new Hero(); h.name = "盖伦"; ADHero ad = new ADHero(); ad.name = "艾希"; APHero ap = new APHero(); ap.name = "安妮"; ADAPHero adap = new ADAPHero(); adap.name = "库奇"; h.kill(ad); h.kill(ap); h.kill(adap); } }
package charactor; public interface AD { public void physicAttack(); }
package charactor; public interface AP { public void magicAttack(); }


HOW2J公众号,关注后实时获知布最新的教程和优惠活动,谢谢。


问答区域    
2018-04-20 交作业-打卡
暄染



package charactor;

import property.Item;
import property.LifePotion;
import property.MagicPotion;

public class Hero {
    public String name;
    protected float hp;
    
    public void kill(Mortal m) {
    	System.out.println(name + "放了一个大招");
    	m.die();
    }
    
    public void useItem(Item i) {
    	i.effect();
    }
      
    public static void main(String[] args) {
        
    	Hero garen = new Hero();
    	garen.name = "盖伦";
    	
    	ADHero adHero = new ADHero();
    	APHero apHero = new APHero();
    	ADAPHero adapHero = new ADAPHero();
    	
    	garen.kill(adHero);
    	garen.kill(apHero);
    	garen.kill(adapHero);
    }  
}
运行结果:

盖伦放了一个大招
adhero死了
盖伦放了一个大招
aphero死了
盖伦放了一个大招
adaphero死了






答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到





2018-04-15 站长大大,提问一下作业
老文氓



public void kill(Mortal m){ System.out.println(name+"放了一个大招"); m.die(); } name指的是哪个对象的名字,运行结果显示: null放了一个大招 艾希这个物理英雄挂了
package Study;
import Study.Item;
import Study.LifePotion;
import Study.MagicPotion;
/**
 * 方法重载练习、对象转型练习 、多态练习、类的多态练习题
 * 英雄类
 * @author lenovo
 *
 */
public class Hero {
	String name;//名字
	int hp;//血量
	
	//类的多态练习
	/*如果物品的种类特别多,那么就需要设计很多的方法,比如useArmor,useWeapon等等
	 *这个时候采用多态来解决这个问题:设计一个方法叫做useItem,其参数类型是Item
	 *如果是使用血瓶,调用该方法,如果是使用魔瓶,还是调用该方法
	 *无论英雄要使用什么样的物品,只需要一个方法即可
	 */
	public void useItem(Item i){//Item i代表传进来的对象,必须继承Item类
		i.effect();
	}
	
	//类的多态练习题,添加一个方法,在这个方法中调用m的die方法
	public void kill(Mortal m){//Mortal m代表传进来的对象,必须实现Mortal这个接口
		System.out.println(name+"放了一个大招");
		m.die();
	}

	public static void main(String[] args) {
		//类型转换指的是把一个引用所指向的对象的类型,转换为另一个引用的类型
		Hero h=new Hero();
		ADHero ad=new ADHero();
		Support s=new Support();
		APHero ap=new APHero();
		
		//子类转父类(向上转型)
		h=ad;//把右边的当做左边的来用(把物理英雄当做普通英雄来用)
		/*ad引用所指向的对象的类型是ADHero,h引用的类型是Hero,把ADHero当做Hero使用,一定可以
		 *子类转换为父类一定可以
		 */
		
		
		//父类转子类(向下转型)
		ad=(ADHero)h;//父类转子类,所以要进行强转
		//h这个引用,所指向的对象是ADHero,所以能转换成功
		
		h=s;//是子类转换为父类,一定可以
		//ad=(ADHero)h;//抛出异常
		//是把h引用所指向的对象 Support,转换为ad引用的类型ADHero, 把物理攻击英雄当成辅助英雄来用,说不通,所以会强制转换失败,并且抛出异常
		
		
		//没有继承关系的类型进行互相转换一定会失败,所以会出现编译错误
		//ad=(ADHero)ap;
		
		
		//实现类转换成接口(向上转型)
		AD adi=ad;//把一个ADHero类型转换为AD接口
		
		
		//接口转换成实现类(向下转型)
		ADHero adhero=(ADHero)adi;//adi实际上是指向ADHero的,所以能够转换成功
		
		//ADAPHero adapHero=(ADAPHero)adi;//adi引用所指向的对象是一个ADHero,要转换成ADAPHero就会失败
		
		
		//instanceof Hero判断一个引用所指向的对象,是否是Hero类型,或者Hero的子类
		Hero h1=ad;
		Hero h2=ap;
		System.out.println(h1 instanceof ADHero);//判断引用h1所指向的对象,是否是ADHero类型
		System.out.println(h2 instanceof APHero);//判断引用h2所指向的对象,是否是APHero类型
		System.out.println(h1 instanceof Hero);//判断引用h1所指向的对象,是否是Hero的子类类型
		
		
		//类的多态练习
		Hero garen=new Hero();
		LifePotion lp=new LifePotion();
		MagicPotion mp=new MagicPotion();
		garen.useItem(lp);
		garen.useItem(mp);
		
		//类的多态练习题
		Hero h3=new Hero();
		h3.name="盖伦";
		ADHero ad1=new ADHero();
		ad1.name="艾希";
		APHero ap1=new APHero();
		ap1.name="安妮";
		ADAPHero adap1=new ADAPHero();
		
		h1.kill(ad1);//运行显示:null放了一个大招 艾希这个物理英雄挂了
	}
}
运行结果:
null放了一个大招
艾希这个物理英雄挂了


2 个答案

埃隆杨 答案时间:2018-04-20
我搞错了,应该是 h1.kill(ad1);这里,h3.kill(ad1),你把上面的例子的h1写到下面来了,建议不要一起写啊

埃隆杨 答案时间:2018-04-20
public String name; //姓名 float hp=100; //血量 -------------------------------- 姓名属性那里少了public




答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到





2018-03-28 name的传值问题
2018-01-27 交作业..
2018-01-27 交一份作业
2018-01-02 提交作业(多态的作用)-------能一看就明白多态的作用,看后你就能理解,简单方便
2017-12-13 交一份作业
2017-12-03 作业 ,看下对不对
2017-11-27 作业
2017-11-18 关于为什么使用重写和多态的 讲解 很棒。。
2017-11-15 关于kill( Mortal m)与 h=kill(ap)
2017-11-10 main方法???主方法也可以写在子类里面.......
2017-09-02 想要输出“盖伦击杀了库奇这个混合英雄”该怎么写呢?
2017-08-01 站长大大,能解释一下此处接口Mortal的作用吗?
2017-07-12 作业
2017-07-11 交作业了----多态
2017-06-24 父类引用指向子类对象,不是很理解
2017-05-23 学习交流
2017-04-26 主函数调kill方法时候报错The method kill(Mortal) in the type Hero is not applicable for the arguments (Hero)
2017-04-15 看了答案还是不太懂具体代码是怎么运行的,在mian方法里是怎么一步步调用的
2017-03-21 接口只能单独放在.java文件中吗
2016-12-18 请问各位大佬,public void kill(Mortal m)中的Mortal m是代表什么?
2016-10-29 示例5的20,21行不是父类对象引用指向子类引用呀
2016-07-23 几个类名不对,LifePotion和LifePortion MagicPotion和MagicPortion




提问之前请登陆
关于 JAVA 基础-接口与继承-多态 的提问

尽量提供截图代码异常信息,有助于分析和解决问题。 也可进本站QQ群交流: 389538688
站长会在每个工作日早上尽量回答提问(如果有漏掉没有回答的,请进群提醒一下)
提问尽量提供完整的代码,环境描述,越是有利于问题的重现,您的问题越能更快得到解答。
对教程中代码有疑问,请提供是哪个步骤,哪一行有疑问,这样便于快速定位问题,提高问题得到解答的速度
站长是玻璃心,提问的时候请语气温柔些 kiss~
截止2017-5-19日累计提问 1638个,站长回答了 1546个
截止2017-8-15日累计提问 2788个,站长回答了 2544个

上传截图