一、练习-治疗
- 先设计一个英雄类(父类),每个英雄都有 name、HP、MP
- 设计一个类Support (辅助英雄)继承Hero,提供一个heal(治疗)方法
- 对Support的heal方法进行重载
heal()
heal(Hero h) //为指定的英雄加血
heal(Hero h, int hp) //为指定的英雄加了hp的血
代码
- Hero英雄类(父类)
public class Hero {//英雄类(主类) //每个英雄都有名字、血量、蓝量 public String name; public int HP; public int MP; }
- Support 辅助英雄类(子类)
public class Support extends Hero{//辅助英雄类(子类) 继承 英雄类 //方法重载 public void heal(){ System.out.println(super.name+"进行了治疗,但不确定治疗了谁"); super.MP -= 10; } public void heal(Hero h1){ System.out.println(super.name+"为"+h1.name+"施展了治疗术"); super.MP -= 10; } public void heal(Hero h1,int HP){ super.MP -= 10; h1.HP += HP; System.out.println(super.name+"为"+h1.name+ "施展了治疗术,HP+"+ HP); } public void heal(int HP,Hero...heroes){ super.MP -= 10; for (int i = 0; i < heroes.length; i++) { heroes[i].HP += HP; System.out.print(super.name+"为"+heroes[i].name+ "施展了治疗术,HP+"+ HP+" "); } } }
- Application总测试类
public class Application {//总测试类 public static void main(String[] args) { //奶妈 500 120 Support naiMa = new Support(); naiMa.name = "奶妈"; naiMa.HP=500; naiMa.MP=120; //盖伦 850 0 Hero gaiLun = new Hero(); gaiLun.name = "盖伦"; gaiLun.HP=850; gaiLun.MP=0; //提莫 600 80 Hero tiMo = new Hero(); tiMo.name = "提莫"; tiMo.HP=600; tiMo.MP=80; //奶妈进行了治疗,但不确定治疗了谁 naiMa.heal(); //奶妈为盖伦施展了治疗术 naiMa.heal(gaiLun); //奶妈为盖伦施展了治疗术,HP+100 naiMa.heal(gaiLun,100); //奶妈为盖伦施展了治疗术,HP+100,奶妈为提莫施展了治疗术,HP+100 naiMa.heal(100,gaiLun,tiMo); System.out.println(); System.out.println("========================="); //当前状态 //奶妈 500 80 System.out.print(naiMa.name+" "); System.out.print(naiMa.HP+" "); System.out.println(naiMa.MP); //盖伦 1050 0 System.out.print(gaiLun.name+" "); System.out.print(gaiLun.HP+" "); System.out.println(gaiLun.MP); //提莫 700 80 System.out.print(tiMo.name+" "); System.out.print(tiMo.HP+" "); System.out.println(tiMo.MP); } }
二、练习-传参判断
在方法中,使参数引用指向一个新的对象
外面的引用是指向原来的对象?还是新的对象?
案例
public class Hero {
String name; //姓名
float hp; //血量
float armor; //护甲
int moveSpeed; //移动速度
public Hero(){
}
public Hero(String name,float hp){
this.name = name;
this.hp = hp;
}
//复活(错误复活方法,此方法生成了新的对象"提莫",而不是在原有的对象"提莫"上做修改)
public void revive(Hero h){//31行跳转21行调用revive的时候,引用h指向 引用teemo所指向的对象 "提莫"
h = new Hero("提莫",383);//在第22行方法体内,引用h指向了一个新的对象 “新的提莫”,原引用h指向引用teemo所指向的对象"提莫"将失效,引用h改为指向新的对象,所以引用teemo所指的原有的对象"提莫"没有任何修改
}
public static void main(String[] args) {
Hero teemo = new Hero("提莫",383);
//受到400伤害,挂了
teemo.hp = teemo.hp - 400;
teemo.revive(teemo);//在第31行,调用revive的时候,引用h指向 引用teemo所指向的对象 "提莫"
System.out.println(teemo.hp);//输出-17.0
//问题: System.out.println(teemo.hp); 输出多少? 怎么理解?
teemo.revive1(teemo);
System.out.println(teemo.hp);//输出383
}
//复活(正确复活方法,要在原有的对象"提莫"上做修改)
public void revive1(Hero h){//调用revive1的时候,引用h指向 引用teemo所指向的对象 "提莫",引用h和引用teemo指向同一个对象"提莫"
h.hp=383;//引用h和引用teemo指向同一个对象"提莫",引用h修改对象"提莫"hp属性,则对象"提莫"hp属性就为383,所以teemo.hp输出为383(原地满血复活)
}
}
在第31行,调用revive的时候,引用h指向 引用teemo所指向的对象 “提莫”
但是teemo引用,还是指向原来的对象
在第22行,引用h指向了新的对象 “新的提莫”而原来的"提莫" 对象,没有做任何修改,血量依然是负数
最后问 teemo这个引用所指向的对象, 就是"死" 掉的 “提莫” 血量,负数
三、练习-多态的经典案例
简单的多态和转型,相信大家都会,最后来个复杂的,一个经典案例:
案例
class A {
public String show(D obj) {
return ("A and D");
}
public String show(A obj) {
return ("A and A");
}
}
class B extends A{
public String show(B obj){
return ("B and B");
}
public String show(A obj){
return ("B and A");
}
}
class C extends B{
}
class D extends B{
}
public class Demo {
public static void main(String[] args) {
A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();
System.out.println("1--" + a1.show(b));//A - A
System.out.println("2--" + a1.show(c));//A - A
System.out.println("3--" + a1.show(d));//A - D
System.out.println("4--" + a2.show(b));//B - A
System.out.println("5--" + a2.show(c));//B - A
System.out.println("6--" + a2.show(d));//A - D
System.out.println("7--" + b.show(b));// B - B
System.out.println("8--" + b.show(c));// B - B
System.out.println("9--" + b.show(d));// A - D
}
}
个人理解(如有误请指教)
——方法调用的优先级问题(优先调用当前类方法,当前类对象,如没有则往上依次调用父类方法、父类对象)
- a1.show( b ) —— a1为A类的引用变量,指向A类的对象;a1为A类,则a1.show( b )应该调用A类中的方法,然而A类中并没有show(B obj)方法,按照继承链中调用方法的优先级来确定,它会在A类中找到show(A obj) ,所以 a1.show( b ) 结果为 A and A
- a1.show( c ) —— a1为A类的引用变量,指向A类的对象;a1为A类,则a1.show( c )应该调用A类中的方法,然而A类中并没有show(C obj)方法,按照继承链中调用方法的优先级来确定,它会在A类中找到show(A obj) ,所以 a1.show( c ) 结果为 A and A
- a1.show( d ) —— a1为A类的引用变量,指向A类的对象;a1为A类,则a1.show( d )应该调用A类中的方法,在A类中有show(D obj)方法,所以 a1.show( d ) 结果为 A and D
- a2.show( b ) —— a2为A类的引用变量,指向B类的对象,此处进行了向上转型,子类单独定义的方法会丢失(B.show(B obj)不能被调用),A.show(A obj)被B.show(A obj)重写;a2为A类,则a2.show( b )应该调用A类中的方法,然而A类中并没有show(B obj)方法,按照继承链中调用方法的优先级来确定,它会在A类中找到被重写的show(A obj) ,所以 a1.show( b ) 结果为 B and A
- a2.show( c ) —— a2为A类的引用变量,指向B类的对象,此处进行了向上转型,子类单独定义的方法会丢失(B.show(B obj)不能被调用),A.show(A obj)被B.show(A obj)重写;a2为A类,则a2.show( c )应该调用A类中的方法,然而A类中并没有show(C obj)方法,按照继承链中调用方法的优先级来确定,它会在A类中找到被重写的show(A obj) ,所以 a1.show( c ) 结果为 B and A
- a2.show( d ) —— a2为A类的引用变量,指向B类的对象,此处进行了向上转型,子类单独定义的方法会丢失(B.show(B obj)不能被调用),A.show(A obj)被B.show(A obj)重写;a2为A类,则a2.show( d )应该调用A类中的方法,在A类中有show(D obj)方法,所以 a1.show( d ) 结果为 A and D
- b.show( b ) —— b为B类的引用变量,指向B类的对象;b为B类,则b.show( b )应该调用B类中的方法,在B类中有show(B obj)方法,所以 b.show( b ) 结果为 B and B
- b.show( c ) —— b为B类的引用变量,指向B类的对象;b为B类,则b.show( c )应该调用B类中的方法,然而B类中并没有show(C obj)方法,按照继承链中调用方法的优先级来确定,它会在B类中找到show(B obj) ,所以 b.show( c ) 结果为 B and B
- b.show( d ) —— b为B类的引用变量,指向B类的对象;b为B类,则b.show( d )应该调用B类中的方法,因为B类是A类的子类,所以B类继承了A类的show(D obj),则在B类中有show(D obj)方法,所以 b.show( d ) 结果为 A and D