一、题目:设计一个游戏项目的基础精灵类(Sprite:游戏中的元素:玩家,怪物,NPC都称之为精灵),所有的精灵都包含以下特征:
属性:图片地址,坐标x,坐标y,宽度和高度等
行为:初始化,绘制到界面,销毁等
现在要求创建不同的精灵子类:玩家类,敌人类,NPC类,这些类对于精灵的的行为都具有不同的实现。
二、设计思路:
先创建一个精灵类作为其他类的父类,在精灵类里面定义他们共有的属性和方法,并用abstract关键字,使初始化、绘制到界面和销毁这三个实现不确定的方法抽象,待到相关子类进行定义,提高了程序的扩展性。
同时,在相关子类中实现了多态,多态是面向对象三大特征中最重要的一种特征。多态可以体现在方法层面,方法层面的多态由重载和重写实现;另外多态最重要的体现在变量层面,可以使用一个父类的引用变量指向任何的子类对象,从而实现引用动态绑定机制。在相关子类中我们对上述三个抽象方法进行了方法重载,同时我们在调用时,对他们进行了上转型的变量层面的多态,使得Elf 可以自由变换为Gamer/Enemy/NPC,提高了程序的可扩展性,使代码更加简洁利于读懂。
三:实现代码:
package com.softeem.classwork07.Game;
/**
* 游戏精灵类
* */
public abstract class Elf {
/**属性::图片地址,坐标x,坐标y,宽度,高度,血量*/
private String Eaddress;
private double Ex;
private double Ey;
private double Eheight;
private double Ewidth;
private double blood;
public String getEaddress() {
return Eaddress;
}
public void setEaddress(String eaddress) {
Eaddress = eaddress;
}
public double getEx() {
return Ex;
}
public void setEx(double ex) {
Ex = ex;
}
public double getEy() {
return Ey;
}
public void setEy(double ey) {
Ey = ey;
}
public double getEheight() {
return Eheight;
}
public void setEeight(double ehight) {
Eheight = ehight;
}
public double getEwidth() {
return Ewidth;
}
public void setEwidth(double ewidth) {
Ewidth = ewidth;
}
public double getBlood() {
return blood;
}
public void setBlood(double blood) {
this.blood = blood;
}
/**行为:初始化,绘制到界面,销毁*/
public abstract void initialize(Elf f) ;
public abstract void print(Elf f);
public abstract void destory(Elf f);
}
/**玩家类*/
public class Gamer extends Elf{
private int index = 0;
Gamer[] ga = new Gamer[10];
@Override
public void initialize(Elf g) {
if(g!=null) {
g =new Gamer();
ga[index++] = (Gamer) g;
print(g);
}
}
@Override
public void print(Elf g) {
if(g!=null) {
g =new Gamer();
System.out.print("玩家地址:" + g.getEaddress() + "\t");
System.out.print("玩家x坐标:" + g.getEx()+ "\t");
System.out.print("玩家y坐标:" + g.getEy() + "\t");
System.out.print("玩家高度:" + g.getEheight() + "\t");
System.out.print("玩家宽度:" + g.getEwidth() + "\t");
System.out.println("玩家血量:" + g.getBlood()+ "\t");
}
}
@Override
public void destory(Elf g) {
g =new Gamer();
for(int i = 0;i< ga.length;i++) {
if(g!=null&&ga[i]==g) {
ga[i] =null;
System.arraycopy(ga, i + 1, ga, i, ga.length - (i + 1));
}
}
}
}
/**敌人类*/
public class Enemy extends Elf{
private int index = 0;
Enemy[] en = new Enemy[10];
@Override
public void initialize(Elf e) {
if(e!=null) {
e =new Enemy();
en[index++] = (Enemy)e;
print(e);
}
}
@Override
public void print(Elf e) {
if(e!=null) {
e =new Enemy();
en[index++] = (Enemy)e;
System.out.print("敌人地址:" + e.getEaddress() + "\t");
System.out.print("敌人x坐标:" + e.getEx()+ "\t");
System.out.print("敌人y坐标:" + e.getEy() + "\t");
System.out.print("敌人高度:" + e.getEheight() + "\t");
System.out.print("敌人宽度:" + e.getEwidth() + "\t");
System.out.println("敌人血量:" + e.getBlood()+ "\t");
}
}
@Override
public void destory(Elf e) {
e =new Enemy();
for(int i = 0;i< en.length;i++) {
if(e!=null&&en[i]==e&&e.getBlood()==0) {
en[i] =null;
System.arraycopy(en, i + 1,en, i, en.length - (i + 1));
}
}
}
}
/NPC类/
public class NPC extends Elf{
private int index = 0;
NPC[] npc = new NPC[10];
@Override
public void initialize(Elf n) {
if(n!=null) {
n =new NPC();
npc[index++] = (NPC) n;
print(n);
}
}
@Override
public void print(Elf n) {
if(n!=null) {
n =new NPC();
System.out.print("NPC地址:" + n.getEaddress() + "\t");
System.out.print("NPCx坐标:" + n.getEx()+ "\t");
System.out.print("NPCy坐标:" + n.getEy() + "\t");
System.out.print("NPC高度:" + n.getEheight() + "\t");
System.out.print("NPC宽度:" + n.getEwidth() + "\t");
System.out.println("NPC血量:" + n.getBlood()+ "\t");
}
}
@Override
public void destory(Elf n) {
n =new NPC();
for(int i = 0;i< npc.length;i++) {
if(n!=null&&npc[i]==n) {
npc[i] =null;
System.arraycopy(npc, i + 1,npc, i, npc.length - (i + 1));
}
}
}
}
四、总结:
abstract和动态绑定的灵活使用能够使得程序的可扩展性大大提高,同时也减少了代码的重复,达到了使得代码简介易懂的目的。