潜艇游戏第五天:
潜艇游戏第一天:
- 设计6个类,设计World类并测试
潜艇游戏第二天:
- 给6个类添加构造方法,并测试
潜艇游戏第三天:
- 设计SeaObject超类,6个类继承SeaObject
- 给SeaObject设计两个构造方法,6个派生类分别调用
- 设计潜艇数组、水雷数组、深水炸弹数组,并测试
潜艇游戏第四天:
- 在6个类中重写move()移动
- 给类中成员添加访问控制修饰符
- 设计Images图片类
潜艇游戏第五天:
-
将窗口的宽和高设计为常量,适当地方做修改
-
画窗口:在World类中—共3步,不要求掌握,Ctrl C/V
- import JFrame和JPanel
- 设计World类继承JPanel
- CV大法
-
画海洋图、画对象
1)想画对象需要去获取对象的图片,每个对象都能获取图片, 意味着获取图片行为为共有的行为,所以设计在SeaObject中, 每个对象获取图片的行为都是不一样的,所以设计为抽象方法 ----在SeaObject中设计getImage()获取对象的图片 2)在6个派生类中重写getImage()获取对象的图片 ----重写getImage() 3)因为只有活着的对象才需要画到窗口中,所以需要设计对象的状态, 每个对象都有状态,意味着状态为共有属性,所以设计在SeaObject中, 状态一般设计为常量,同时设计state变量表示当前状态 ----在SeaObject中设计LIVE、DEAD常量,state变量表示当前状态 后期的业务中还需要判断状态,每个对象都得判断状态, 意味着判断状态行为为共有的行为,所以设计在SeaObject中, 每个对象判断状态的行为都是一样的,所以设计为普通方法 ----在SeaObject中设计isLive()、isDead()判断对象的状态 4)数据都有了就可以开画了,每个对象都能画, 意味着画对象的行为为共有行为,所以设计在SeaObject中, 每个对象画的行为都是一样的,所以设计为普通方法 ----在SeaObject中设计paintImage()画对象 5)画对象的行为做好了,在窗口World中调用即可: 5.1)准备对象 5.2)重写paint()画方法
回顾:
-
方法的重写(override):重新写、覆盖
- 发生在父子类中,方法名相同,参数列表相同
- 重写方法被调用时,看对象的类型
派生类觉得超类的行为不够好,想修改需要重写
-
重写与重载的区别:
- 重写:发生在父子类中,方法名相同,参数列表相同
- 重载:发生在同一类中,方法名相同,参数列表不同
-
package和import:
-
访问控制修饰符:实现封装,暴露与隐藏-----保护数据的安全
- public:公开的,任何类
- protected:受保护的,本类、派生类、同包类
- 默认的:什么也不写,本类、同包类----------------java不建议
- private:私有的,本类
-
static:静态的
-
静态变量:static,属于类,方法区,一份,类名点来访问
所有对象所共享的数据(图片、音频、视频等)
-
静态方法:static,属于类,方法区,一份,类名点来访问
静态方法没有隐式this传递,不能直接访问实例成员
方法的操作与对象无关
-
静态块:static,属于类,在类被加载期间自动执行,一次
初始化/加载静态资源(图片、音频、视频等)
-
笔记:
-
final:最终的,不可改变的-----------单独应用几率低
-
修饰变量:变量不能被改变
//演示final修饰变量 class Aoo{ final int num = 5; void show(){ //num = 55; //编译错误,final的变量不能被改变 } }
-
修饰方法:方法不能被重写
//演示final修饰方法 class Boo{ final void show(){} } class Coo extends Boo{ //void show(){} //编译错误,final修饰的方法不能被重写 }
-
修饰类:类不能被继承
//演示final修饰类 final class Doo{} //class Eoo extends Doo{} //编译错误,final的类不能被继承 class Foo{} final class Goo extends Foo{} //不能当老爸,但能当儿子
-
-
static final常量:应用率高
- 必须声明同时初始化
- 通过类名点来访问,不能被改变
- 建议:常量名所有字母都大写,多个单词用_分隔
- 编译器在编译时会将常量直接替换为具体的值,效率高
- 何时用:数据永远不变,并且经常使用
public class StaticFinalDemo { public static void main(String[] args) { System.out.println(Hoo.PI); //通过类名点来访问 //Hoo.PI = 3.1415926; //编译错误,常量不能被改变 //1)加载Ioo.class到方法区中 //2)将静态变量num一并存储到方法区中 //3)到方法区中获取num的值并输出 System.out.println(Ioo.num); //编译器在编译时将常量直接替换为具体的值,效率高 //相当于System.out.println(5); System.out.println(Ioo.COUNT); } } class Ioo{ public static int num = 5; //静态变量 public static final int COUNT = 5; //常量 } class Hoo{ public static final double PI = 3.14159; //public static final int NUM; //编译错误,常量必须声明同时初始化 }
-
抽象方法:
- 由abstract修饰
- 只有方法的定义,没有具体的实现(连{}都没有)
-
抽象类:
-
由abstract修饰
-
包含抽象方法的类必须是抽象类
-
抽象类不能被实例化(new对象)
-
抽象类是需要被继承的,派生类:
- 重写所有抽象方法--------------变不完整为完整
- 也声明为抽象类------------------一般不这么做
-
抽象类的意义:
-
封装共有的属性和行为--------------------代码复用
-
为所有派生类提供统一的类型-----------向上造型—代码复用
-
可以包含抽象方法,为所有派生类提供统一的入口(能点出来)
派生类的行为不同,但入口是一致的,同时相当于定义了一个标准
-
-
精华笔记:
-
final:最终的,不可改变的-----------单独应用几率低
- 修饰变量:变量不能被改变
- 修饰方法:方法不能被重写
- 修饰类:类不能被继承
-
static final常量:应用率高
- 必须声明同时初始化
- 通过类名点来访问,不能被改变
- 建议:常量名所有字母都大写,多个单词用_分隔
- 编译器在编译时会将常量直接替换为具体的值,效率高
- 何时用:数据永远不变,并且经常使用
-
抽象方法:
- 由abstract修饰
- 只有方法的定义,没有具体的实现(连{}都没有)
-
抽象类:
-
由abstract修饰
-
包含抽象方法的类必须是抽象类
不包含抽象方法的类也可以声明为抽象类-------------了解
-
抽象类不能被实例化(new对象)
-
抽象类是需要被继承的,派生类:
- 重写所有抽象方法--------------变不完整为完整
- 也声明为抽象类------------------一般不这么做
-
抽象类的意义:
-
封装共有的属性和行为--------------------代码复用
-
为所有派生类提供统一的类型-----------向上造型—代码复用
-
可以包含抽象方法,为所有派生类提供统一的入口(能点出来)
派生类的行为不同,但入口是一致的,同时相当于定义了一个标准
-
-
补充:
-
设计规则:
-
将派生类所共有的属性和行为,抽到超类中-------------抽共性
-
派生类的行为都一样,则设计为普通方法
派生类的行为不一样,则设计为抽象方法
-
------------下周二讲
-
-
抽象方法/抽象类的疑问:
-
抽象方法的存在意义是什么?
- 保证当发生向上造型时,通过超类型的引用能点出来那个方法
-
既然意义只在于能点出来,那为什么不设计为普通方法?
- 若设计为普通方法,则派生类可以重写也可以不重写,而设计为抽象方法,可以强制派生类必须重写------做了个标准,强制必须重写
-
面向对象第五天标准作业:
列表:
1、在World类中设计窗口的宽和高为常量,在SeaObject的两个参构造中将数据修改为常量
2、画窗口:不要求掌握,CV即可
3、画海洋图、画对象:
—在超类中设计抽象方法getImage(),派生类中重写
—在超类中设计状态常量及当前状态变量,设计isLive()、isDead()判断状态
—在超类中设计paintImage()画图片
—在main中重写paint()调用paintImage()方法
1、在World类中设计窗口的宽和高为常量,在SeaObject的两个参构造中将数据修改为常量。。参考代码:
package day05;
//整个游戏世界
public class World {
public static final int WIDTH = 641;
public static final int HEIGHT = 479;
public static void main(String[] args) {
SeaObject[] submarines = new SeaObject[5]; //潜艇(侦察潜艇、鱼雷潜艇、水雷潜艇)
submarines[0] = new ObserveSubmarine();
submarines[1] = new ObserveSubmarine();
submarines[2] = new TorpedoSubmarine();
submarines[3] = new TorpedoSubmarine();
submarines[4] = new MineSubmarine();
for(int i=0;i<submarines.length;i++){
System.out.println(submarines[i].x+","+submarines[i].y);
submarines[i].move();
}
Battleship s = new Battleship();
Mine[] ms = new Mine[2];
ms[0] = new Mine(100,200);
ms[1] = new Mine(200,400);
for(int i=0;i<ms.length;i++){
System.out.println(ms[i].x+","+ms[i].y);
ms[i].move();
}
Bomb[] bs = new Bomb[2];
bs[0] = new Bomb(100,200);
bs[1] = new Bomb(200,400);
for(int i=0;i<bs.length;i++){
System.out.println(bs[i].x+","+bs[i].y);
bs[i].move();
}
}
}
package day05;
import java.util.Random;
//海洋对象
public class SeaObject {
protected int width;
protected int height;
protected int x;
protected int y;
protected int speed;
public SeaObject(int width,int height){
this.width = width;
this.height = height;
x = -width;
Random rand = new Random();
y = rand.nextInt(World.HEIGHT-height-150)+150;
speed = rand.nextInt(3)+1;
}
public SeaObject(int width,int height,int x,int y,int speed){
this.width = width;
this.height = height;
this.x = x;
this.y = y;
this.speed = speed;
}
public void move(){
System.out.println("海洋对象移动");
}
}
//注:其余类没有变化,此处省略
2、画窗口。。参考代码:
package day05;
import javax.swing.JFrame;
import javax.swing.JPanel;
//整个游戏世界
public class World extends JPanel {
public static final int WIDTH = 641;
public static final int HEIGHT = 479;
public static void main(String[] args) {
JFrame frame = new JFrame();
World world = new World();
world.setFocusable(true);
frame.add(world);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(WIDTH+16, HEIGHT+39);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
//注:其余类没有变化,此处省略
3、画海洋图、画对象:
—在超类中设计抽象方法getImage(),派生类中重写
—在超类中设计状态常量及当前状态变量,设计isLive()、isDead()判断状态
—在超类中设计paintImage()画图片
—在main中重写paint()调用paintImage()方法
参考代码:
package day05;
import javax.swing.ImageIcon;
import java.awt.Graphics;
import java.util.Random;
//海洋对象
public abstract class SeaObject {
public static final int LIVE = 0;
public static final int DEAD = 1;
protected int state = LIVE; //当前状态
protected int width;
protected int height;
protected int x;
protected int y;
protected int speed;
public SeaObject(int width,int height){
this.width = width;
this.height = height;
x = width;
Random rand = new Random();
y = rand.nextInt(World.HEIGHT-height-150)+150;
speed = rand.nextInt(3)+1;
}
public SeaObject(int width,int height,int x,int y,int speed){
this.width = width;
this.height = height;
this.x = x;
this.y = y;
this.speed = speed;
}
public abstract void move();
public abstract ImageIcon getImage();
public boolean isLive(){
return state==LIVE;
}
public boolean isDead(){
return state==DEAD;
}
public void paintImage(Graphics g){
if(isLive()){
this.getImage().paintIcon(null,g,this.x,this.y);
}
}
}
package day05;
import javax.swing.ImageIcon;
//战舰
public class Battleship extends SeaObject {
private int life;
public Battleship(){
super(66,26,270,124,20);
life = 5;
}
public void move(){
System.out.println("战舰移动");
}
public ImageIcon getImage(){
return Images.battleship;
}
}
package day05;
import javax.swing.ImageIcon;
//侦察潜艇
public class ObserveSubmarine extends SeaObject {
public ObserveSubmarine(){
super(63,19);
}
public void move(){
System.out.println("侦察潜艇x向右移动");
}
public ImageIcon getImage(){
return Images.obsersubm;
}
}
package day05;
import javax.swing.ImageIcon;
//鱼雷潜艇
public class TorpedoSubmarine extends SeaObject {
public TorpedoSubmarine(){
super(64,20);
}
public void move(){
System.out.println("鱼雷潜艇x向右移动");
}
public ImageIcon getImage(){
return Images.torpesubm;
}
}
package day05;
import javax.swing.ImageIcon;
//水雷潜艇
public class MineSubmarine extends SeaObject {
public MineSubmarine(){
super(63,19);
}
public void move(){
System.out.println("水雷潜艇x向右移动");
}
public ImageIcon getImage(){
return Images.minesubm;
}
}
package day05;
import javax.swing.ImageIcon;
//水雷
public class Mine extends SeaObject {
public Mine(int x,int y){
super(11,11,x,y,1);
}
public void move(){
System.out.println("水雷y向上移动");
}
public ImageIcon getImage(){
return Images.mine;
}
}
package day05;
import javax.swing.ImageIcon;
//深水炸弹
public class Bomb extends SeaObject {
public Bomb(int x,int y){
super(9,12,x,y,3);
}
public void move(){
System.out.println("深水炸弹y向下移动");
}
public ImageIcon getImage(){
return Images.bomb;
}
}
package day05;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
//整个游戏世界
public class World extends JPanel {
public static final int WIDTH = 641;
public static final int HEIGHT = 479;
private Battleship ship = new Battleship(); //战舰
private SeaObject[] submarines = {
new ObserveSubmarine(),
new TorpedoSubmarine(),
new MineSubmarine()
}; //潜艇(侦察潜艇、鱼雷潜艇、水雷潜艇)
private Mine[] mines = {
new Mine(260,200)
}; //水雷
private Bomb[] bombs = {
new Bomb(200,190)
}; //深水炸弹
public void paint(Graphics g){
Images.sea.paintIcon(null,g,0,0); //画海洋图
ship.paintImage(g);
for(int i=0;i<submarines.length;i++){
submarines[i].paintImage(g);
}
for(int i=0;i<mines.length;i++){
mines[i].paintImage(g);
}
for(int i=0;i<bombs.length;i++){
bombs[i].paintImage(g);
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
World world = new World();
world.setFocusable(true);
frame.add(world);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(WIDTH+16, HEIGHT+39);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
//注:其余类没有变化,此处省略