掌握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分支代替),简化书写

总结

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

相关推荐
plmm烟酒僧1 分钟前
Windows下QT调用MinGW编译的OpenCV
开发语言·windows·qt·opencv
测试界的酸菜鱼12 分钟前
Python 大数据展示屏实例
大数据·开发语言·python
让学习成为一种生活方式16 分钟前
R包下载太慢安装中止的解决策略-R语言003
java·数据库·r语言
Mephisto.java16 分钟前
【大数据学习 | kafka高级部分】kafka中的选举机制
大数据·学习·kafka
晨曦_子画22 分钟前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
Black_Friend30 分钟前
关于在VS中使用Qt不同版本报错的问题
开发语言·qt
南宫生44 分钟前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法
希言JY1 小时前
C字符串 | 字符串处理函数 | 使用 | 原理 | 实现
c语言·开发语言
残月只会敲键盘1 小时前
php代码审计--常见函数整理
开发语言·php
xianwu5431 小时前
反向代理模块
linux·开发语言·网络·git