2.用一个简单的pk小游戏深刻理解继承

我们来写一个pk类小游戏深刻理解一下继承:

public class LiuBei {
    // 属性
    String name;
    int ad;
    int hp;

    // PK 攻击的是一种类型
    public void ack_1(LvBu lvbu) {
        lvbu.hp = lvbu.hp - this.ad;
        System.out.println(this.name + "攻击了" + lvbu.name);
        System.out.println(lvbu.name + "失去了" + this.ad + "点HP");
        System.out.println(lvbu.name + "还剩下" + lvbu.hp + "点HP");
    }
}
public class LvBu{

        String name;
        int ad;
        int hp;

        // PK 攻击的是一种类型
        public void ack_1(LiuBei liubei){
            liubei.hp = liubei.hp - (this.ad*2);
            System.out.println (this.name + "攻击了" + liubei.name);
            System.out.println (liubei.name+"失去了"+(this.ad*2)+"点HP");
            System.out.println (liubei.name+"还剩下"+liubei.hp+"点HP");
        }


    }
public class Entrance{
    public static void main(String[] args){
        // 先创建双方对象
        LvBu lvbu = new LvBu ();
        LiuBei liubei = new LiuBei ();
        // 给对象的属性赋值
        lvbu.name="吕布";
        lvbu.hp=2000;
        lvbu.ad=130;

        liubei.name="刘备";
        liubei.hp=1800;
        liubei.ad=150;

        int count=0;
        while(lvbu.hp>0&&liubei.hp>0){
            System.out.println ("-----第"+(++count)+"回合----");
            // 互相攻击了一次
            lvbu.ack_1 (liubei);
            if(liubei.hp>0){// 被攻击之后 再判断一次生命值
                liubei.ack_1(lvbu);
            }

        }

    }
}

        这几段代码出现后,我们可以很明显的看到,在吕布,刘备这两个类中,有代码冗余。这仅仅是两个简单的人物,我们想一想,假如我们一个人物需要写1000行代码,我们的游戏中有108个人物,那么总计就有108000行代码。 

        于是我们就要思考一个问题,能否将这些人物共同的功能写在一个类中,让每个人物都来“继承”这个类中的功能?假如我们每个人物之间重复的代码大约是400行,那么我们每个人物只需要编写600行,用刚提到的策略,代码行数总共为400+600*108=65200,少了42800行代码,一下子使代码行数少了一大半,并且可以有更好的维护性。

        从这个例子可以看出,人物之间共同的代码越多,继承效果越好,实际上,两个任务的共同的功能很可能超过了一半。上述策略就叫做继承,继承是面向对象的重要特征。在java中,被继承的类叫父类、基类或者超类,与之对应的叫子类或派生类。

       我们就以这个pk游戏为例,他们都有攻击功能,且属性均为姓名、攻击值、生命力,因此将两个类共同的部分写成一个类——Hero,让两个人物刘备和吕布继承它即可。

public class Hero {
    String name;
    int ad;
    int hp;

    public void ack(Hero h){
        h.hp=h.hp-this.ad;
        System.out.println(this.name+"攻击了"+h.name);
        System.out.println(h.name+"失去了"+this.ad+"点HP");
        System.out.println(h.name+"还剩下"+h.hp+"点HP");
    }

    public void move(){
        System.out.println(this.name+"每秒移动1米");
    }
}

两个子类如下:

public class LiuBei extends Hero{

    //重写父类的方法
    @ Override    //重写方法的检查注解
    public void move(){
        System.out.println(this.name+"每秒移动2米");
    }
}
public class LvBu extends Hero{

    //重写父类的方法
    @ Override    //重写方法的检查注解
    public void ack(Hero h){
            h.hp = h.hp - (this.ad*2);
            System.out.println (this.name + "攻击了" + h.name);
            System.out.println (h.name+"失去了"+(this.ad*2)+"点HP");
            System.out.println (h.name+"还剩下"+h.hp+"点HP");
        }


    }
public class Entrance{
    public static void main(String[] args){
        // 先创建双方对象
        LvBu lvbu = new LvBu ();
        LiuBei liubei = new LiuBei ();
        // 给对象的属性赋值
        liubei.name="吕布";
        liubei.hp=2000;
        liubei.ad=130;

        lvbu.name="刘备";
        lvbu.hp=1800;
        lvbu.ad=150;

        int count=0;
        while(lvbu.hp>0&&liubei.hp>0){
            System.out.println ("-----第"+(count++)+"回合----");
            // 互相攻击了一次
            lvbu.ack (liubei);
            lvbu.move();
            if(liubei.hp>0){// 被攻击之后 再判断一次生命值
                liubei.ack(lvbu);
                liubei.move();
            }

        }

    }
}

       从表面看,虽然刘备和吕布类都没有定义成员变量,但他们继承了父类的成员变量,可以i当作自己的变量一样使用。他们各自也继承或修改了父类的方法,具体不再阐述。

       为了便于理解,我们再写一个书上的例子。以字体对话框和段落对话框为例,为了简化起见,假如字体对话框特征是标题、字体名称,该对话库具有显示的功能;段落对话框特征是标题、高度,该对话框具有显示的功能。

       显然,这两个对话框都有标题和显示功能,因此首先将两个类共同的部分写成一个类——Dialog。

public class Dialog {
    protected String title;
    public void show(){
        System.out.println(title+"对话框显示");
    }
}

       接下来编写字体对话框类FontDialog来继承Dialog类。

public class FontDialog extends Dialog {
    private String fontName;
    public FontDialog(String title,String fontName){
        this.title=title;
        this.fontName=fontName;
    }
}

        从表面上看,该类只定义了一个成员变量fontName,实际上还从父类继承了title,可以当成自己的变量一样使用。

        下面用一个主函数进行测试:

public class Entrance{
    public static void main(String[] args) {
        FontDialog fd=new FontDialog("字体","宋体");
        fd.show();
        
    }
}

       显然,FontDialog从父类那里继承了show方法,也能当成自己方法一样来使用。

       注:如果一个成员要被子类继承之后使用,这个成员不能是private,因为私有的成员不能在类的外部使用,当然也不能被子类使用。一般情况下,成员变量定义为protected类型,成员函数定义为public类型。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值