掌握Java封装:以猜拳小游戏为例,深入理解OOP

前言

Java的核心思想是面向对象,面向对象的三大特性分别是:封装、继承、多态

面向对象编程的概念

我的理解:

面向对象是一种编程思想,目的是可以让我们联系现实逻辑,进行复杂的编程(就是以现实的逻辑进行编程)

我们可能听说过面向过程的编程语言,例如c语言就是面向过程。面向过程指的是编写一个个函数来解决问题,编写的函数一个个代码块,即书写解决问题的步骤。

但是现在我们使用面向过程进行编程逐渐力不从心,在大型项目开发中无法解决我们期望写出易维护,易扩展和易复用的需求。此时面向对象思想出现(面向对象,就是将"万物认为是一个个对象",我们操作数据时,只需关注它属于哪个对象,操作方法时,只需要关注它来自哪个方法),这样我们书写代码的方式进行转变,不在是编写一个个解决问题的步骤(面向过程),而是关注解决问题的方式(面向对象)。这样可以大大提高代码的开发效率。

封装的概念

封装 :在Java中,封装指的是将属性私有化,并对外提供可以操作属性的方法。目的是保护对象的数据不被外界任意访问。

广义上封装:就是将数据和数据操作封装起来,进而保证安全性。

类是创建对象的模版,创建一个个对象需要借助类对象,本质上对象也是某种意义上的封装,这种封装使得我们可以便捷的进行复杂的程序操作

基于猜拳案例,了解OOP(面向对象)的实践

需求分析:

执行流程分析:

复制代码
**************************
**********猜拳游戏开始*********
**************************
出拳规则:1:剪刀;2:石头;3:布
请选择对方的角色(1:刘备;2:孙权;3:曹操)
2
请输入你的姓名:
袁绍
袁绍你选择孙权对战
请出拳:1:剪刀;2:石头、3:布
2
你出拳:石头
孙权出拳:布
真菜,你输给了孙权
还要再玩一局么?true/false
true
**************************
**********猜拳游戏开始*********
**************************
出拳规则:1:剪刀;2:石头;3:布
请出拳:1:剪刀;2:石头、3:布
1
你出拳:剪刀
孙权出拳:石头
真菜,你输给了孙权
还要再玩一局么?true/false
true
**************************
**********猜拳游戏开始*********
**************************
出拳规则:1:剪刀;2:石头;3:布
请出拳:1:剪刀;2:石头、3:布
3
你出拳:布
孙权出拳:石头
真牛:你战胜了孙权
还要再玩一局么?true/false
true
**************************
**********猜拳游戏开始*********
**************************
出拳规则:1:剪刀;2:石头;3:布
请出拳:1:剪刀;2:石头、3:布
1
你出拳:剪刀
孙权出拳:布
真牛:你战胜了孙权
还要再玩一局么?true/false
true
**************************
**********猜拳游戏开始*********
**************************
出拳规则:1:剪刀;2:石头;3:布
请出拳:1:剪刀;2:石头、3:布
1
你出拳:剪刀
孙权出拳:布
真牛:你战胜了孙权
还要再玩一局么?true/false
false
袁绍	VS	孙权
对阵次数:5; 平手次数:0
姓名	得分
孙权	2
袁绍	3
袁绍以3 比 2 取得最后的胜利!

在实现任务需求时,我们需要抓取关键点,以程序的思想考虑问题(面向对象)

关键点:玩家,电脑,和猜拳功能

可以得到两个对象,玩家对象和电脑对象,猜拳作为对象的方法(一个方法代表一个功能实现)

源代码:

一共可以定义三个类:电脑实体类(Computer),顾客实体类(Customer),游戏测试类(Game)

Computer类

java 复制代码
public class Computer {
    public String name;
    public int score;
    public int caiquan;

    public void showFirst(){
        caiquan=(int)(Math.random()*3+1);
        switch(caiquan){
            case 1:System.out.println(name+"出拳:剪刀");break;
            case 2:System.out.println(name+"出拳:石头");break;
            case 3:System.out.println(name+"出拳:布");break;
        }
    }
}
  • 定义三个属性,分别表示电脑名name,电脑得分score,电脑出拳caiquan
  • 定义一个方法:表示随机出拳

Customer类

java 复制代码
import java.util.Scanner;

public class Customer {
    public String name;
    public int score;
    public int caiquan;
    Scanner sc=new Scanner(System.in);

    public void showFirst(){
        do{
            System.out.println("请出拳:1:剪刀;2:石头、3:布");
            caiquan=sc.nextInt();
            switch(caiquan){
                case 1:System.out.println("你出拳:剪刀");break;
                case 2:System.out.println("你出拳:石头");break;
                case 3:System.out.println("你出拳:布");break;
                default:System.out.println("你出错了");
            }
        }while(caiquan<0||caiquan>3);
    }

}

Customer和Computer的组成非常相似,只不过,程序不能限定玩家输入任意数据,因此需要加上权限校验机制(当输入的猜拳序号不在范围内,打印错误信息,并重复进入循环)

Game类

java 复制代码
import java.util.Scanner;

public class Game {

    Customer cs ;
    Computer cp ;
    int count = 0;// 对战次数
    Scanner sc = new Scanner(System.in);

    public void welcome() {
        System.out.println("**************************");
        System.out.println("**********猜拳游戏开始*********");
        System.out.println("**************************");
    }

    public void menu() {
        int choose = 0;
        do {
            System.out.println("出拳规则:1:剪刀;2:石头;3:布");
            if(cp.name==null){
                System.out.println("请选择对方的角色(1:刘备;2:孙权;3:曹操)");
                choose = sc.nextInt();
                System.out.println("请输入你的姓名:");
                cs.name=sc.next();
                switch (choose) {
                    case 1:
                        System.out.println(cs.name+"选择刘备对战");
                        cp.name = "刘备";
                        break;
                    case 2:
                        System.out.println(cs.name+"你选择孙权对战");
                        cp.name = "孙权";
                        break;
                    case 3:
                        System.out.println(cs.name+"你选择曹操对战");
                        cp.name = "曹操";
                        break;
                    default:
                        System.out.println(cs.name+"你输错了,请重新选择");
                }
            }
        } while (choose < 1 && choose > 3);

    }

    public void showResult(){

        switch(cs.caiquan){
            case 1://你出拳剪刀
                switch(cp.caiquan){
                    case 1:System.out.println("有两下子:你和"+cp.name+"打了平手");break;
                    case 2:System.out.println("真菜,你输给了"+cp.name);cp.score++;break;
                    case 3:System.out.println("真牛:你战胜了"+cp.name);cs.score++;break;
                }
                break;
            case 2://你出拳石头
                switch(cp.caiquan){
                    case 2:System.out.println("有两下子:你和"+cp.name+"打了平手");break;
                    case 3:System.out.println("真菜,你输给了"+cp.name);cp.score++;break;
                    case 1:System.out.println("真牛:你战胜了"+cp.name);cs.score++;break;
                }
                break;
            case 3://你出拳布
                switch(cp.caiquan){
                    case 3:System.out.println("有两下子:你和"+cp.name+"打了平手");break;
                    case 1:System.out.println("真菜,你输给了"+cp.name);cp.score++;break;
                    case 2:System.out.println("真牛:你战胜了"+cp.name);cs.score++;break;
                }
                break;
        }
        count++;//比赛次数加1
    }

    public void report(){
        System.out.println(cs.name+"\tVS\t"+cp.name);
        System.out.println("对阵次数:"+count+"; 平手次数:"+(count-cs.score-cp.score));
        System.out.println("姓名\t得分");
        System.out.println(cp.name+"\t"+cp.score);
        System.out.println(cs.name+"\t"+cs.score);
        if(cp.score>cs.score){
            System.out.println(cp.name+"以"+cp.score+" 比 "+cs.score+" 取得最后的胜利!");
        }else if(cp.score<cs.score){
            System.out.println(cs.name+"以"+cs.score+" 比 "+cp.score+" 取得最后的胜利!");
        }else{
            System.out.println(cp.name+"以"+cp.score+" 比 "+cs.score+" 战平对手!");
        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Game game=new Game();
        game.cs= new Customer();
        game.cp=new Computer();
        Scanner sc=new Scanner(System.in);
        do{
            game.welcome();
            game.menu();
            game.cs.showFirst();
            game.cp.showFirst();
            game.showResult();
            System.out.println("还要再玩一局么?true/false");
        }while(sc.nextBoolean());
        game.report();

    }

}

核心:

  • 将重复的功能封装成方法
  • 使用双重switch分支(可以用多重if分支代替),简化书写

总结

深刻理解,面向对象编程的思考方式,基于对象进行编程可以快速理解业务需求,并且将重复的功能(代码块),封装成方法,并反复调用,可以提供书写效率,提高代码的阅读性。

相关推荐
车载测试工程师14 小时前
CAPL学习-SOME/IP交互层-符号数据库访问类函数
学习·tcp/ip·以太网·capl·canoe
BD_Marathon14 小时前
Vue3_简介和快速体验
开发语言·javascript·ecmascript
摇滚侠14 小时前
面试实战 问题三十四 对称加密 和 非对称加密 spring 拦截器 spring 过滤器
java·spring·面试
xqqxqxxq14 小时前
Java 集合框架之线性表(List)实现技术笔记
java·笔记·python
L0CK14 小时前
RESTful风格解析
java
程序员小假14 小时前
我们来说说 ThreadLocal 的原理,使用场景及内存泄漏问题
java·后端
何中应14 小时前
LinkedHashMap使用
java·后端·缓存
tryxr14 小时前
Java 多线程标志位的使用
java·开发语言·volatile·内存可见性·标志位
暗然而日章14 小时前
C++基础:Stanford CS106L学习笔记 13 特殊成员函数(SMFs)
c++·笔记·学习
talenteddriver14 小时前
java: Java8以后hashmap扩容后根据高位确定元素新位置
java·算法·哈希算法