目录
1.前言---为什么要运用继承
之前的PK游戏有了大致的创建思路,基于此预估一下代码量,如果一个hero的一个攻击方法4行代码,一个hero可攻击99个hero,那么100个hero则需要100*99*4,如果在再在此的基础上增加攻击方法/hero,代码量将无比巨大。所以应用一种更优化的方法是必要的。
2.继承是什么
2.1继承的内涵解释:
2.11继承是类与类之间的“关系”
······以学生类为例·····
...................................
·其中上级类是下一级类的父类,父类又称SuperClass
·每个级类都只能有一个直系的父类,父类的父类称作父系类,作用效果等同于父类;
·创建对象都是通过某一个类创建的,这个对象自然就可以成为这个类的对象
例如
小明属于软件工程专业学生类
小明是一名大学生
小明是一名学生
代码中可以使用子类本身对象变量名以及父类类型对象变量名同时表示(指向)同一个对象。
2.12子类可以继承父类的什么?
子类可以继承父类的属性和方法
创建父类的目的:将所有子类都具备的属性和方法都可以定义在父类中,子类就不需要重复创建了(也就是前言所提到的优化代码量,使它看起来不那么恐怖)。
2.13继承的原则---访问权修饰符
·public :公共的
···可以修饰类/属性/方法:在整个项目下都可以使用
···public修饰的类,类名必修与所在的文件名一致,在一个类文件中只能存在一个主类
·private :私有的
···可以修饰属性和方法:属性和方法只能在类中使用
·protected : 受保护的
···可以修饰属性和方法 :可以同一个包下使用,但是在不同包中的子类中也可以使用。
·缺省不写: 包默认
···可以修饰类/属性/方法
···修饰类的时候不需要与文件名一致,一个类文件中可以存在多个
2.2继承的作用--方法重写
上次提到了方法重载:同一个类中可以创建多个同名的方法,前提是要求参数不一致。
本次的方法重写:子类重写父类的方法,前提是要求参数/方法名/访问权限修饰符/返回值类型必须一致
方法的结构与父类一致 方法体可以修改 重构
作用: 子类可以在父类方法的基础上进行扩展 升级 具体化逻辑
只要重写了父类的方法,不再继承父类的方法,优先调用重写之后的方法
2.3子类与父类的转型
自动转型
A a = new B();//A是B的父类
以父类作为参数类型,之后只要是子类类型对象,都可以作为参数传入适应
同时也方便了系统之后的扩展,只要继承父类就可以与这个方法适配
3.代码实现
//①创建父类,确定属性与方法
public class Hero {
public String nameID;
public int hp;
public int ad;
public int lv;
public Hero(String nameID, int hp, int ad, int lv){
this.nameID=nameID;
this.hp=hp;
this.ad=ad;
this.lv=lv;
}
public void upLv(int hp, int ad) {
lv++;
this.ad += ad;
this.hp += hp;
System.out.println(nameID + "升级了,等级是:"+lv+"现在的生命值是:" +this.hp);
}
public void atk(Hero hero) {//atk(是攻击的一类对象)
// 计算伤害值 // 计算中使用到了浮点数 结果赋值给整数时需要转型 int i =(int)(1.2+5.7); i==6
int num = (int) (100 + lv * 50 + ad * 0.8);//不同hero升级的数值不一样就需要在每个类中进行方法重写,可在一下三类hero任务中查看,此处的数值是张飞类的数值
//也或者 父类中不写该方法,仅在子类中列出
hero.hp -= num;
System.out.println(nameID + "攻击了" + hero.nameID + "使其失去了" + num + "点HP,其 还剩下" + hero.hp + "点HP.");
}
}}
//②依次创建目标子类,一定要注意继承的代码格式
public class ZhangFei extends Hero{
public ZhangFei(String nameID, int hp, int ad, int lv){
//继承父类属性的代码格式!!
super(nameID,hp,ad,lv);
}
public void atk(Hero hero) {
// 计算伤害值 // 计算中使用到了浮点数 结果赋值给整数时需要转型 int i =(int)(1.2+5.7); i==6
int num = (int) (100 + lv * 50 + ad * 0.8);
hero.hp -= num;
System.out.println(nameID + "攻击了" + hero.nameID + "使其失去了" + num + "点HP,其 还剩下" + hero.hp + "点HP.");
}
}
public class LvBu extends Hero {
public LvBu(String nameID, int hp, int ad, int lv) {
super(nameID, hp, ad, lv);
}
public void atk(Hero hero) {
// 计算伤害值 // 计算中使用到了浮点数 结果赋值给整数时需要转型 int i =(int)(1.2+5.7); i==6
int num = (int) (100 + lv * 50 + ad * 1.2);//可以看出进行了方法重写,数值的变化
hero.hp -= num;
System.out.println(nameID + "攻击了" + hero.nameID + "使其失去了" + num + "点HP,其 还剩下" + hero.hp + "点HP.");
}
}
public class HouYi extends Hero{
public HouYi(String nameID, int hp, int ad, int lv) {
//继承父类属性的代码格式!!!
super(nameID, hp, ad, lv);
}
public void atk(Hero hero) {
// 计算伤害值 // 计算中使用到了浮点数 结果赋值给整数时需要转型 int i =(int)(1.2+5.7); i==6
int num = (int) (100 + lv * 50 + ad * 1.3);//方法重写,修改了数值
hero.hp -= num;
System.out.println(nameID + "攻击了" + hero.nameID + "使其失去了" + num + "点HP,其 还剩下" + hero.hp + "点HP.");
}
}
import java.util.Random;
public class PkGame {
public static void main(String[] args) {
// 以张飞类 和 吕布 各自创建一个对象 ,并且对其属性初始化赋值
System.out.println("游戏资源加载中....");
// 利用构造方法 复用赋值的代码
Hero zf1 = new ZhangFei("张飞(ZLL)", 2630, 86, 2);
Hero hy1 = new HouYi("后羿(CNN)", 2730, 86, 2);
Hero lb1 = new LvBu("吕布(OOP)", 2310, 113, 2);
System.out.println("游戏加载完成....");
System.out.println("PK开始");
// 随机数:
Random ran = new Random();
while (zf1.hp > 0 && lb1.hp > 0) {
int r = ran.nextInt(2);// 随机0 1
if (r == 0) {
// zf1.upLv();
lb1.upLv(200,50);//调用继承方法给出具体参数
} else {
zf1.atk (lb1);
if (lb1.hp <= 0) {
break;
}
lb1.atk (zf1);
lb1.atk (lb1);
hy1.atk (lb1);
}
}
}
}
4.总结:
继承真的好用哈哈哈这一次我要缩减我的代码量