ooday05 2022.01.14 面向对象第五天:

ooday05 2022.01.14 面向对象第五天:

潜艇游戏第五天:

潜艇游戏第一天:

  1. 设计6个类,设计World类并测试

潜艇游戏第二天:

  1. 给6个类添加构造方法,并测试

潜艇游戏第三天:

  1. 设计SeaObject超类,6个类继承SeaObject
  2. 给SeaObject设计两个构造方法,6个派生类分别调用
  3. 设计潜艇数组、水雷数组、深水炸弹数组,并测试

潜艇游戏第四天:

  1. 在6个类中重写move()移动
  2. 给类中成员添加访问控制修饰符
  3. 设计Images图片类

潜艇游戏第五天:

  1. 将窗口的宽和高设计为常量,适当地方做修改

  2. 画窗口:在World类中—共3步,不要求掌握,Ctrl C/V

    • import JFrame和JPanel
    • 设计World类继承JPanel
    • CV大法
  3. 画海洋图、画对象

    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()画方法
    

回顾:

  1. 方法的重写(override):重新写、覆盖

    • 发生在父子类中,方法名相同,参数列表相同
    • 重写方法被调用时,看对象的类型

    派生类觉得超类的行为不够好,想修改需要重写

  2. 重写与重载的区别:

    • 重写:发生在父子类中,方法名相同,参数列表相同
    • 重载:发生在同一类中,方法名相同,参数列表不同
  3. package和import:

  4. 访问控制修饰符:实现封装,暴露与隐藏-----保护数据的安全

    • public:公开的,任何类
    • protected:受保护的,本类、派生类、同包类
    • 默认的:什么也不写,本类、同包类----------------java不建议
    • private:私有的,本类
  5. static:静态的

    • 静态变量:static,属于类,方法区,一份,类名点来访问

      ​ 所有对象所共享的数据(图片、音频、视频等)

    • 静态方法:static,属于类,方法区,一份,类名点来访问

      ​ 静态方法没有隐式this传递,不能直接访问实例成员

      ​ 方法的操作与对象无关

    • 静态块:static,属于类,在类被加载期间自动执行,一次

      ​ 初始化/加载静态资源(图片、音频、视频等)

笔记:

  1. 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{} //不能当老爸,但能当儿子
      
  2. 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; //编译错误,常量必须声明同时初始化
    }
    
  3. 抽象方法:

    • 由abstract修饰
    • 只有方法的定义,没有具体的实现(连{}都没有)
  4. 抽象类:

    • 由abstract修饰

    • 包含抽象方法的类必须是抽象类

    • 抽象类不能被实例化(new对象)

    • 抽象类是需要被继承的,派生类:

      • 重写所有抽象方法--------------变不完整为完整
      • 也声明为抽象类------------------一般不这么做
    • 抽象类的意义:

      • 封装共有的属性和行为--------------------代码复用

      • 为所有派生类提供统一的类型-----------向上造型—代码复用

      • 可以包含抽象方法,为所有派生类提供统一的入口(能点出来)

        派生类的行为不同,但入口是一致的,同时相当于定义了一个标准

精华笔记:

  1. final:最终的,不可改变的-----------单独应用几率低

    • 修饰变量:变量不能被改变
    • 修饰方法:方法不能被重写
    • 修饰类:类不能被继承
  2. static final常量:应用率高

    • 必须声明同时初始化
    • 通过类名点来访问,不能被改变
    • 建议:常量名所有字母都大写,多个单词用_分隔
    • 编译器在编译时会将常量直接替换为具体的值,效率高
    • 何时用:数据永远不变,并且经常使用
  3. 抽象方法:

    • 由abstract修饰
    • 只有方法的定义,没有具体的实现(连{}都没有)
  4. 抽象类:

    • 由abstract修饰

    • 包含抽象方法的类必须是抽象类

      不包含抽象方法的类也可以声明为抽象类-------------了解

    • 抽象类不能被实例化(new对象)

    • 抽象类是需要被继承的,派生类:

      • 重写所有抽象方法--------------变不完整为完整
      • 也声明为抽象类------------------一般不这么做
    • 抽象类的意义:

      • 封装共有的属性和行为--------------------代码复用

      • 为所有派生类提供统一的类型-----------向上造型—代码复用

      • 可以包含抽象方法,为所有派生类提供统一的入口(能点出来)

        派生类的行为不同,但入口是一致的,同时相当于定义了一个标准

补充:

  1. 设计规则:

    • 将派生类所共有的属性和行为,抽到超类中-------------抽共性

    • 派生类的行为都一样,则设计为普通方法

      派生类的行为不一样,则设计为抽象方法

    • ------------下周二讲

  2. 抽象方法/抽象类的疑问:

    • 抽象方法的存在意义是什么?

      • 保证当发生向上造型时,通过超类型的引用能点出来那个方法
    • 既然意义只在于能点出来,那为什么不设计为普通方法?

      • 若设计为普通方法,则派生类可以重写也可以不重写,而设计为抽象方法,可以强制派生类必须重写------做了个标准,强制必须重写

面向对象第五天标准作业:

列表:
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);
    }
}

//注:其余类没有变化,此处省略
上一篇:基于Vue脚手架2.6的框架项目开发使用axios请求接口使用


下一篇:Activity Result API 使用与源码分析,面试阿里P7岗