day16--ooday10(submarine项目:水雷与战舰碰撞、检测游戏结束、画状态:游戏结束、回顾:面向对象的三大特征、String字符串类型、常量池)
1.submarine项目
-
水雷与战舰的碰撞:
-
在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();
-
-
检测游戏结束:
-
借用Battleship中的getLife()获取命数
-
检测游戏结束为定时发生的,所以在run中调用checkGameOverAction()实现检测结束
-
在checkGameOverAction()中:
判断若战舰的命数<=0,表示游戏结束了,则将当前状态修改为GAME_OVER
-
代码
//在World中设计checkGameOverAction()方法
checkGameOverAction(){
if(ship.getLife()<=0){
state=GAME_OVER;
}
}
-
-
画状态:
-
在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.面向对象的三大特征
-
封装
-
类:封装的是对象的行为和属性
-
方法:封装的是具体的业务逻辑的实现
-
访问控制修饰符:封装的是具体的访问的权限,以保护数据安全
-
-
继承
-
作用:代码复用
-
超类:所有派生类所共有的行为和属性
接口:部分派生类所共有的行为和属性
派生类:派生类所特有的行为和属性
-
单一继承,多接口实现,具有传递性
-
-
多态:
-
行为多态:所有抽象方法都是多态的(通过方法的重写实现的)】
-
对象多态:所有对象都是多态的(通过向上造型来实现)
-
向上造型、强制类型转换、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不同了
*/
}
}
-