软工中级实训——Part4问答题

文章目录

Part4: Interacting Objects解答

一、The Critter Class

1. What methods are implemented in Critter?

  • 答案: Critter中共实现了6个方法:
    • act()
    • getActors()
    • processActors()
    • getMoveLocations()
    • selectMoveLocation()
    • makeMove()
  • 原因及源码支撑:
    /* @file: framework/info.gridworld.actor/Critter.java */
    /* @line: 38、56、71、88、104、125 */
    public void act()
    public ArrayList<Actor> getActors()
    public void processActors(ArrayList<Actor> actors)
    public ArrayList<Location> getMoveLocations()
    public Location selectMoveLocation(ArrayList<Location> locs)
    public void makeMove(Location loc)
    

2. What are the five basic actions common to all critters when they act?

  • 答案: 从act方法实现可以知道5个公共方法为:
    • getActors()
    • processActors()
    • getMoveLocations()
    • selectMoveLocation()
    • makeMove()
  • 原因及源码支撑:
    /* @file: framework/info.gridworld.actor/Critter.java */
    /* @line: 38~47 */
    public void act()
    {
        if (getGrid() == null)
            return;
        ArrayList<Actor> actors = getActors();
        processActors(actors);
        ArrayList<Location> moveLocs = getMoveLocations();
        Location loc = selectMoveLocation(moveLocs);
        makeMove(loc);
    }
    

3. Should subclasses of Critter override the getActors method? Explain.

  • 答案: 应该
  • 原因: 因为不同的Critter选择actors的方式可能有不同,因此我们需要Override该方法以针对性地选择actors

4. Describe the way that a critter could process actors.

  • 答案: 以源代码为例,我们可以选择吃掉(即移除)所有不是critter也不是rock的actors
  • 原因及源码支撑:
    /* @file: framework/info.gridworld.actor/Critter.java */
    /* @line: 71~78 */
    public void processActors(ArrayList<Actor> actors)
    {
        for (Actor a : actors)
        {
            if (!(a instanceof Rock) && !(a instanceof Critter))
                a.removeSelfFromGrid();
        }
    }
    

5. What three methods must be invoked to make a critter move? Explain each of these methods.

  • 答案: critter移动应调用的3个必备方法为:
    • getMoveLocations()
    • selectMoveLocation()
    • makeMove()
  • 解释及源码支撑:
    为实现critter的移动,act应按下面3步调用方法
    • 首先act方法会调用getMoveLocations方法获得所有可选位置集: 在标准critter中,它选择周围8格里面所有的空白方格;

      /* @file: framework/info.gridworld.actor/Critter.java */
      /* @line: 88~91 */
      public ArrayList<Location> getMoveLocations()
      {
          return getGrid().getEmptyAdjacentLocations(getLocation());
      }
      
    • 然后调用selectMoveLocation方法以某种方法选择其中一个位置: 在标准critter中,会从上一步得到的Location集合中随机选择一个位置并返回。

      /* @file: framework/info.gridworld.actor/Critter.java */
      /* @line: 104~111 */
      public Location selectMoveLocation(ArrayList<Location> locs)
      {
          int n = locs.size();
          if (n == 0)
              return getLocation();
          int r = (int) (Math.random() * n);
          return locs.get(r);
      }
      
    • 最后调用makeMove方法将critter移动到上一步选定的位置

      /* @file: framework/info.gridworld.actor/Critter.java */
      /* @line: 125~131 */
      public void makeMove(Location loc)
      {
          if (loc == null)
              removeSelfFromGrid();
          else
              moveTo(loc);
      }
      

6. Why is there no Critter constructor?

  • 答案: 因为Critter是继承自Actor类的,这里Critter类有默认构造器,其中会调用super()方法调用Actor类的构造器,从而创建对象。

二、Extending the Critter Class

1. Why does act cause a ChameleonCritter to act differently from a Critter even though ChameleonCritter does not override act?

  • 答案: 因为从上面已知act类中会用到5个基本方法,而在ChameleonCritter类中override了其中的两个方法processActors以及makeMove方法,因此最终导致ChameleonCritter类中的行为与其父类Critter不同。
  • 源码支撑:
    /* @file: projects/critters/ChameleonCritter.java */
    /* @line: 36 */
    public void processActors(ArrayList<Actor> actors)
    /* @line: 50 */
    public void makeMove(Location loc)
    

2. Why does the makeMove method of ChameleonCritter call super.makeMove?

  • 答案: 在ChameleonCritter类中的makeMove方法实际上是先将自身方向转至新方向,然后再调用父类的makeMove方法,这样直接复用了父类的代码,减少冗余。
  • 源码支撑:
    /* @file: projects/critters/ChameleonCritter.java */
    /* @line: 50~54 */
    public void makeMove(Location loc)
    {
        setDirection(getLocation().getDirectionToward(loc));
        super.makeMove(loc);
    }
    

3. How would you make the ChameleonCritter drop flowers in its old location when it moves?

  • 答案: 我们可以重写makeMove方法: 用一个变量记录移动前ChameleonCritter的位置,移动后与原位置比较: 如果一样的话我们就不留花;否则我们就在原位置留下一朵花。
  • 代码支撑: 将下面的代码覆盖掉原来的makeMove方法即可实现要求
    /* @file: projects/critters/ChameleonCritter.java */
    /* @origin_line: 50~54 */
    public void makeMove(Location loc)
    {
        Location oldLocation = getLocation();
        setDirection(getLocation().getDirectionToward(loc));
        super.makeMove(loc);
        if (oldLocation != loc) {
            Flower flower = new Flower();
            flower.putSelfInGrid(getGrid(), oldLocation);
        }
    }
    

4. Why doesn’t ChameleonCritter override the getActors method?

  • 答案: 因为ChameleonCritter类对要处理的actors的需求跟父类Critter是一样的,因此不需要override父类的getActors方法,直接继承即可。

5. Which class contains the getLocation method?

  • 答案: Actor类,所有Actor的子类通过继承来使用此方法。
  • 源码支撑:
    /* @file: framework/info.gridworld.actor/Actor.java */
    /* @line: 102~105 */
    public Location getLocation()
    {
        return location;
    }
    

6. How can a Critter access its own grid?

  • 答案: 通过调用getGrid方法,因为在Actor类中已经实现了此方法,而Critter类是Actor类的子类,直接继承了父类的getGrid方法。
  • 源码支撑:
    /* @file: framework/info.gridworld.actor/Actor.java */
    /* @line: 92~95 */
    public Grid<Actor> getGrid()
    {
        return grid;
    }
    

三、Another Critter

1. Why doesn’t CrabCritter override the processActors method?

  • 答案: 因为CrabCritter类对于得到的Actor的处理方法是一样的,都是直接移除,因此我们可以直接继承父类Critter的processActors方法而无需override
  • 原因及源码支撑:
    /* @file: framework/info.gridworld.actor/Critter.java */
    /* @line: 71~78 */
    public void processActors(ArrayList<Actor> actors)
    {
        for (Actor a : actors)
        {
            if (!(a instanceof Rock) && !(a instanceof Critter))
                a.removeSelfFromGrid();
        }
    }
    

2. Describe the process a CrabCritter uses to find and eat other actors. Does it always eat all neighboring actors? Explain.

  • 答案及原因: CrabCritter的getActors方法只会在正前方、左前方和右前方这3个方向的相邻格中寻找Actor,而找到之后它会调用processActors方法将其中非石头以及非critter的所有Actor都"吃掉"。因此实际上它只"吃"前方3个方向中的部分Actor,并未"吃掉"所有相邻的Actor。
  • 源码支撑:
    /* @file: projects/critters/CrabCritter.java */
    /* @line: 47~48 */
    // 说明只获取前方3个方向
    int[] dirs =
        { Location.AHEAD, Location.HALF_LEFT, Location.HALF_RIGHT };
    /* @line: 49~54 */
    // 说明只获取非空Actor
    for (Location loc : getLocationsInDirections(dirs))
    {
        Actor a = getGrid().get(loc);
        if (a != null)
            actors.add(a);
    }
    
    /* @file: framework/info.gridworld.actor/Critter.java */
    /* @line: 75~76 */
    // 说明不"吃"rock和其他critter
    if (!(a instanceof Rock) && !(a instanceof Critter))
        a.removeSelfFromGrid();
    

3. Why is the getLocationsInDirections method used in CrabCritter?

  • 答案:
      因为CrabCritter的定义中,吃的时候(getActors)需要得到前3个方向的Location;而移动的时候(getMoveLocations)则需要得到左右两个方向的Location,在这之前并没有哪个方法能实现到按方向范围集合搜索这一点。

      因此我们定义该方法,传入需要的Direction值集合作为参数,从而得到对应的Location。这样可以复用代码,减少冗余。
  • 原因及源码支撑:
    /* @file: projects/critters/CrabCritter.java */
    /* @line: 44~49 */
    public ArrayList<Actor> getActors()
    {
        ArrayList<Actor> actors = new ArrayList<Actor>();
        int[] dirs =
            { Location.AHEAD, Location.HALF_LEFT, Location.HALF_RIGHT };
        for (Location loc : getLocationsInDirections(dirs))
    
    /* @line: 62~67 */
    public ArrayList<Location> getMoveLocations()
    {
        ArrayList<Location> locs = new ArrayList<Location>();
        int[] dirs =
            { Location.LEFT, Location.RIGHT };
        for (Location loc : getLocationsInDirections(dirs))
    

4. If a CrabCritter has location (3, 4) and faces south, what are the possible locations for actors that are returned by a call to the getActors method?

  • 答案: (4, 3)、(4, 4)和(4, 5)
  • 原因: 从CrabCritter的getActors方法实现中可以知道CrabCritter会往其前方3个方向中寻找,而此时CrabCritter正面朝南方,因此它的前方3个方向即为答案中所写的。
  • 源码支撑:
    /* @file: projects/critters/CrabCritter.java */
    /* @line: 44~49 */
    public ArrayList<Actor> getActors()
    {
        ArrayList<Actor> actors = new ArrayList<Actor>();
        int[] dirs =
            { Location.AHEAD, Location.HALF_LEFT, Location.HALF_RIGHT };
        for (Location loc : getLocationsInDirections(dirs))
    

5. What are the similarities and differences between the movements of a CrabCritter and a Critter?

  • 答案及源码支撑:
    • 相似处:

      • (1) 它们在移动的时候都不会选择转向;(移动的时候loc == null为false,都会调用moveTo方法移动)

        /* @file: framework/info.gridworld.actor/Critter.java */
        /* @line: 125~131 */
        public void makeMove(Location loc)
        {
            if (loc == null)
                removeSelfFromGrid();
            else
                moveTo(loc);
        }
        
      • (2) 它们都是在getMoveLocations方法得到的集合中随机选择下一个移动的。(代码中loc即为上一步得到的可移动位置集合)

        /* @file: framework/info.gridworld.actor/Critter.java */
        // selectMoveLocation方法
        /* @line: 109~110 */
        int r = (int) (Math.random() * n);
        return locs.get(r);
        
    • 不同点:

      • (1) CrabCritter只会往左右两个方向移动;而Critter则可以往8个方向移动。

        /* @file: projects/critters/CrabCritter.java */
        /* @line: 62~67 */
        public ArrayList<Location> getMoveLocations()
        {
            ArrayList<Location> locs = new ArrayList<Location>();
            int[] dirs =
                { Location.LEFT, Location.RIGHT };
            for (Location loc : getLocationsInDirections(dirs))
        
        /* @file: framework/info.gridworld.actor/Critter.java */
        /* @line: 88~91 */
        public ArrayList<Location> getMoveLocations()
        {
            return getGrid().getEmptyAdjacentLocations(getLocation());
        }
        
      • (2) CrabCritter不能移动时会随机往两个方向转向,而Critter会选择停在原地不转向

        /* @file: projects/critters/CrabCritter.java */
        // makeMove方法
        /* @line: 79~88 */
        if (loc.equals(getLocation()))
        {
            double r = Math.random();
            int angle;
            if (r < 0.5)
                angle = Location.LEFT;
            else
                angle = Location.RIGHT;
            setDirection(getDirection() + angle);
        }
        

6. How does a CrabCritter determine when it turns instead of moving?

  • 答案: 通过检查makeMove中的loc参数跟当前位置是否一致,一致的话就选择turn
  • 原因及源码支撑:
    /* @file: projects/critters/CrabCritter.java */
    // makeMove方法
    /* @line: 79 */
    if (loc.equals(getLocation()))
    

7. Why don’t the CrabCritter objects eat each other?

  • 答案: 因为CrabCritter继承自Critter,而子类中并未override掉processActors方法,因此CrabCritter类使用的仍是父类Critter的。而在父类的定义中,该方法会"吃掉"所有非rock及非Critter的Actor,而CrabCritter继承自Critter,自然不会被"吃掉"。
  • 原因及源码支撑:
    /* @file: framework/info.gridworld.actor/Critter.java */
    /* @line: 71~78 */
    public void processActors(ArrayList<Actor> actors)
    {
        for (Actor a : actors)
        {
            if (!(a instanceof Rock) && !(a instanceof Critter))
                a.removeSelfFromGrid();
        }
    }
    
    /* @file: projects/critters/CrabCritter.java */
    /* @line: 32 */
    public class CrabCritter extends Critter
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值