day16--ooday10(submarine项目:水雷与战舰碰撞、检测游戏结束、画状态:游戏结束、回顾:面向对象的三大特征、String字符串类型、常量池)

day16--知识回顾

1.submarine项目

  1. 水雷与战舰的碰撞:

    • 在Battleship中设计subtractLife()减命

    • 水雷与战舰的碰撞为定时发生的,所以在run中调用mineBangAction()实现水雷与战舰碰撞在mineBangAction()中:

    • 在mineBangAction中遍历所有水雷得到水雷,判断若都或者并且还撞上了:

      水雷去死、战舰减命

    • 代码

      //battleship中,设计减命方法
      public void subtract(){
         life--;
      }
      //在World中,设计水雷碰撞方法

      public void mingBangAction(){
         for(int i=0;i<mines.length;i++){
             Mine m=mines[i];
              if(m.isLive()&&s.isLive()&&ship.isHit(m)){
             m.goDead();
             s.subtract();
        }
        }
       
      }

      //在action中的run,调用
      mineBangActionLife();

       

  2. 检测游戏结束:

    • 借用Battleship中的getLife()获取命数

    • 检测游戏结束为定时发生的,所以在run中调用checkGameOverAction()实现检测结束

    • 在checkGameOverAction()中:

      判断若战舰的命数<=0,表示游戏结束了,则将当前状态修改为GAME_OVER

    • 代码

      //在World中设计checkGameOverAction()方法
      checkGameOverAction(){
         if(ship.getLife()<=0){
             state=GAME_OVER;
        }
      }

       

  3. 画状态:

    • 在World中设计RUNNING,GAME_OVER状态常量,变量state表示窗口当前状态

    • 在paint()中设计:

      • 游戏结束状态是,画游戏结束图

      • 运行状态时,画海洋、对象们、分和名

    • 代码

      //在World中
      public static final int RUNNING=0;
      public static final int GAME_OVER=1;
      private int state=RUNNING;
      //在paint中
      public void paint(Graphics g){
         switch(state){
             case GAME_OVER:
                 Images.gameover.paintIcon(null,g,0,0);
                break;
                     
             case RUNNING:
                ....
        }
      }

       

     

2.面向对象的三大特征

  1. 封装

    • 类:封装的是对象的行为和属性

    • 方法:封装的是具体的业务逻辑的实现

    • 访问控制修饰符:封装的是具体的访问的权限,以保护数据安全

  2. 继承

    • 作用:代码复用

    • 超类:所有派生类所共有的行为和属性

      接口:部分派生类所共有的行为和属性

      派生类:派生类所特有的行为和属性

    • 单一继承,多接口实现,具有传递性

  3. 多态:

    • 行为多态:所有抽象方法都是多态的(通过方法的重写实现的)】

    • 对象多态:所有对象都是多态的(通过向上造型来实现)

    • 向上造型、强制类型转换、instanceof判断

3.String字符串类型

  • java.lang.String使用final修饰,不能被继承

  • Java中的String在内存中采用Unicode编码方式,任何一个字符占用两个字节的编码

  • 字符串底层封装的是一个字符数组

  • 字符串一旦创建,对象内容永远无法改变,但字符串引用可以重新赋值---不变对象

  • 常量池:

    • Java对字符串有一个优化措施:字符串常量池(堆中)

    • java推荐我们使用字面量/直接量方式来创建字符串,并且会缓存所有以字面量/直接量的形式创建的字符串对象到常量池,当使用相同字面量字符串再创建对象时,将复用常量池的对象以减小内存开销,从而避免内存堆积大量内容相同的字符串对象

    • 代码

      package ooday10;
      //String的演示
      public class StringDemo {
         public static void main(String[] args) {
             String s1 = "123abc"; //堆中创建一个123abc对象,常量池中存储这个对象的引用

             //编译器在编译时,若发现是两个字面量连接,
             //则直接运算好并将结果保存起来,如下代码相当于String s2="123abc";
             String s2 = "123"+"abc"; //复用常量池中的123abc对象
             System.out.println(s1==s2); //true

             String s3 = "123";
             //因为s3不是字面量,所以并不会直接运算结果
             String s4 = s3+"abc"; //会在堆中创建新的123abc对象,而不会重用常量池中的对象
             System.out.println(s1==s4); //false







             /*
               使用字面量来创建字符串对象时,JVM会检查常量池中是否有该对象:
                1)若没有,则会创建该字符串对象并存入常量池中
                2)若有,则直接将常量池中的对象返回(不会再创建新的字符串对象)
              */
             /*
             String s1 = "123abc"; //常量池还没有,因此创建该字符串对象,并存入常量池
             String s2 = "123abc"; //常量池中已经有了,直接重用对象
             String s3 = "123abc"; //常量池中已经有了,直接重用对象
             //引用类型==,比较地址是否相同
             System.out.println(s1==s2); //true
             System.out.println(s1==s3); //true
             System.out.println(s2==s3); //true

             s1 = s1+"!"; //创建新的字符串对象并将地址赋值给s1
             System.out.println(s1==s2); //false,因为s1为新对象的地址,与s2不同了
             */

        }
      }

       

 

posted @ 2022-03-21 21:11  约拿小叶  阅读(43)  评论(0)    收藏  举报