面向对象与魔兽争霸

介绍:
       面向对象:现代软件开发的一种常用思想。
       魔兽争霸:一款极具艺术性的即时战略游戏。
说明:
       此篇仅是我以魔兽为基础理解面向对象,并不代表魔兽就是这样设计的。
       谨以此篇献给我的程序设计和魔兽争霸。
正文:
       面向对象的根本思想就是“万事万物皆对象”。何谓对象?对象就是描述客观事物的实体,它将自己的属性和操作封装在自己的内部而只对外提供接口。魔兽中的每个实体也可以看成一个个的对象。无论是恶魔猎手、死亡骑士等英雄,还是女猎、狼骑等兵种、甚至无敌药水、传送权杖等商品都可以看成对象,她们也都有自己的属性和操作。魔兽中的万事万物皆对象,就像黑客帝国中的人将万事万物视为01一般。
       对象来自类的实例化,每个对象都含有自己的属性和操作。魔兽中的每个对象也都有自己的属性和操作,如DK,有自己属性:敏捷度、智力值、生命值、魔法值;操作:四个魔法:死亡缠绕、死亡契约、邪恶光环、操纵死尸等。
如:
class Obj {
       objAttribute1 x;
       objAtribute2 y;
       ……..
       public void Obj() {
              …..
}
       public void objOperate1() {
              …..
}
public void objOperate2() {
       …..
}
}
class newObj {
       public void newObjOperate() {
              Obj obj1 = new Obj();
              Obj obj2 = new Obj();
}
}
       其中Obj为某个类,含有属性x、y和操作objOperate1、objOperate2。newObj为一专门进行实例化的类,它实例化出了Obj的两个对象obj1、obj2。魔兽中的每个对象      也是可以看成有类事例化而来。
如:
//死亡骑士类
class DeadKing {
       DeadKing DKInstance = null;
       Image[] DKimg;     //包含DK的一组图片,用于显示时贴图
       int lifevalue;           //生命值
       int magicvalue;       //魔法值
       int degree;             //等级
       TeasureBasket[6] tbasket;      //宝物篮,通过对象聚合记录DK身上带的宝物。
       boolean isInvulnerable;   //是否无敌
       ………                         //其它一些相关属性如:攻击力、护甲、敏捷、智力等
 
       //使用单件创建一个DK实例
       public static synchronized DeadKing getInstance() {
                if (instance==null)
                         DKInstance = new DeadKing();
                return DKInstance;   
}
//相关属性的初始化;
private DeadKing() {
       lifevalue =
       magicvalue =
       isInvulnerable = false;
       ……….
}
//魔兽画面的贴图,也许是用动画做的
public Image putImage() {
       Image img;
       //判断方向选取正确的贴图;
       switch(index) {
              case north :     img = DKImg[0]; break;
              case south:     img = DKImg[1]; break;
              case east:        img = DKImg[2]; break;
              ………
              case dead:       img = DKImg[n]; break;
              ………
              default:   
                            img = null; break;
        }
        return img;
}
//使用Bean来设置和获取lifevalue,magicvalue的操作类似
public void setLifeValue(int lifevalue) {
       this.lifevalue = liftvalue;
}
 
public int getLifeValue() {
       return lifevalue;
}
//当吃生命药剂时使用此方法,至于是生命药剂还是强力生命药剂则在吃生命药剂的事件响应中进行//判断再赋上相应的addvalue然后调用次方法实现;
public void addLifeValue(int addvalue) {
       lifevalue += addvalue;
}
//被攻击减生命值
Public void subtractLifeValue(int subvalue) {
       Lifevalue -= subvalue;
}
//…….魔法的操作与生命值的类似
//还有些相关属性的操作,如宝物篮中有速度之靴,加敏捷度之类的。
 
//魔法
//死亡缠绕
public void deathCoil() {
       magicvalue -= 75;
       ………………
}
//死亡契约
public void deathPact() {
       Magicvalue -= 50;
       ………………..
}
//邪恶光环
public void unholyAura() {
       ………………..
}
//操纵死尸
public void animateDead() {
       magicvalue -= 175;
       ……….
}
}
 
//无敌药水类
class Invulnerability {
       Image img;
       int delaytime;
       ……..
       public Invulnerability() {
              ………..
}
//持续时间
public int getDelayTime() {
       return delaytime;
}
…………..
}
       说明:对于DK类中将构造方法设置为private又增添了一个getInstance的方法是因为DK属于英雄,只能有一个实例(要是能产一队的英雄就NB了),所以此处采用了Singleton模式来实现。其实上面的例子都是那种简易版的,实际上用设计模式来实现会更具威力性,比如使用Factory模式、Proxy模式、Builder模式等等。
 
面向对象思想的特点:
封装性
       从上面的两个例子可以很清楚的看到,在面向对象设计中,一般都把对象封装得很紧密而只对外提供接口,通常属性值都被设置为private,若要对属性进行读取和修改则要通过方法的get和set实现,而仅将对象所要对外公开的接口方法设置为public给用户使用。因此对象是一个封装良好的黑盒子,我们只能通过接口来访问它。
面向对象的新观点是对象是负有责任的一个实体(<<设计模式精解>>一书中的观点)。每个对象都对自己负责,所以对象内部的细节不需要暴露给外界对象,这也就是封装性。比如当我们选中恶魔猎手再右键单击地图上的某一位置,则恶魔猎手这个对象在获取了地图的坐标之后有责任知道该怎么走才能到达目的地,而不再需要控制程序的参与。也就是用户给出要实现什么,具体的实现细节由对象内部实现,用户无权也不必知道。
封装使得对象为自己的行为负越多的责任,控制程序所负的责任就越少,程序也就更加清晰,产生的副作用也就越少。封装也使对象内部对外界是透明的,外界只能通过接口来访问对象。
 
继承性
       抽象类是为一组概念上相似的类定义方法和公共属,它能被实例化。
       派生类是特殊化于一个超类的类。它包含超类所有属性和方法,但还可以包含另外的属性和不同的方法实现。
       继承性指的就是派生类(子类)继承抽象类(基类、父类),它是一种类特殊化的方式,用于联系派生类和抽象类。
比如魔兽中的商品一般可以分为三类:
永久型:速度之靴、贵族头环、火焰篷衣、灵巧头巾、各族的球等。
消费型:生命药剂、魔法药剂、回城卷轴、重生十字章等。
补充型:治疗权杖、水晶球、幻影权杖、飓风权杖等。
因此可以对某一类型的商品设置一个基类,使用永久型商品为例。
Abstract class PermanentTreasure {        //永久型宝物
         ..............
         public abstract void function() ;
                   ...............
}
 
Class SpeedBoots extends PermanentTreasure {       //速度之靴
         public void function() {
                   ..............
}
}
 
       class NobilityCirclet extends PermanentTreasure {      //贵族头环
              public void function() {
                     ……….
}
}
再举一个例子,以四族中的“农民”(暗夜族叫小精灵、兽族叫苦工、人族叫农民、不死族叫侍僧)为例。
小精灵特性:
属性:生命值、攻击力、护甲、移动速度等
方法:采集、建造、修理、自爆等
苦工特性:
       属性:生命值、攻击力、护甲、移动速度等
       方法:采集、建造、修理、掠夺等。
农民特性:   
       属性:生命值、攻击力、护甲、移动速度等
       方法:采集、建造、修理、紧急动员(变民兵)等
侍僧特性:
       属性:生命值、攻击力、护甲、移动速度等
       方法:采集、建造、修理、回收、献祭等
从上面的比较我们可以看出四族农民的属性和方法差不多,所以可以设置一个基类,然后将每族农民设为一个子类。
       Abstract class Farmer {
              int lifevalue;
              int beatvalue;
              int armorvalue;
              int speedvalue;
              …….
              public Farmer() {
                     ……
}
              public abstract void gather() ;
              public abstract void build();
              public abstract void repair();
              ……….
}
 
Class NEFarmer extends Farmer {
              ……
       Public NEFarmer() {
              //设置相关属性
}
public void gather() {
       ……..
}
              public void build() {
                     ………
}
              public void repair() {
                     ………..
}
//自爆
Public void detonate() {
       ………
}
……….
}
其他三族的类与NE的类的编写类似只是有些方法不同(各族各自的特点),如兽族的掠夺、人族的变民兵、不死族的献祭等。
 
多态性
       多态性指的是相关的对象按照各自类型来实现方法的能力,它与继承性连接得很紧密。多态性有可分为编译时多态和运行时多态。编译时多态是指在编译阶段就可确定,运行时多态要等到运行阶段才能确定。以继承类中的四族农民的例子为例,从上面我们可以看到四族农民有一些共同的方法。
       比如:
              Farmer fInstance = new Farmer();
              NEFarmer nefInstance = new NEFarmer();
              HMFarmer hmfInstance = new HMFarmer();
              ORCFarmer orcfInstance = new ORCFarmer();
              UDFarmer udfInstance = new UDFarmer();
 
              fInstance = nefInstance;
              fInstance.gather();         //采用NE的采集方式
              fInstance = hmfInstance;
              fInstance.build();           //采用HM的建造方式
              fInstance = orcfInstance;
              fInstance.repair();         //采用ORC的修理方式
              fInstance = udfInstance;
              fInstance.gather();         //采用UD的采集方式
 
       以上就是运行时多态了,它是等到运行时通过判定对象所属的类型再去执行相应类型所对应的方法的。
总结:
       面向对象的思想是博大精深的,要想精通绝非易事。这里只是对面向对象的一些基本概念和特点结合魔兽争霸进行了介绍而已,还须继续钻研。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值