从石头剪刀布开始的Java学习(第二章)

从石头剪刀布开始的Java学习(第二章),第1张

文章目录
  • 前言
  • 一、石头剪刀布的原始代码的实现
    • 1.一个错误的示范
      • 1.人手势
      • 2.电脑手势
      • 3.判断 *** 作
      • 4.错误的地方
        • 1.equal方法
  • 二、项目改良方向
    • 1.判断方法
      • 1.接口
      • 2.实现类
      • 3.判断方法的升级
    • 1.用户的升级
      • 1.抽象类
      • 2.抽象方法
        • 1.方法重载与方法重写的区别
        • 2.抽象方法的重载
          • 1.人类
          • 2.电脑类
        • 3.接口方法重载
  • 3.具体代码的实现
    • 1.User类
    • 2.人和电脑类
    • 3.接口以及实现类
    • 4.main函数
  • 总结


前言

这一章节主要是会对抽象类和接口,还有java一些常用的API进行一个讲解,也会讲到代码的原始实现到利用算法的进行的改进实现。


一、石头剪刀布的原始代码的实现 1.一个错误的示范

上一章节中我们没有对出的动作进行一个说明。那么我们初学者最开始的想法一定会是直接在控制台上,进行一个手势的读入,然后电脑那一边我们也会希望进行直接一个手势的输出,然后在函数进行一个判断行为。

1.人手势

这对人这一边来讲,实现是非常之简单的。我们来看看人这一边的实现代码吧!

public String personGuesture;

Scanner in = new Scanner(System.in);
String personGuesture = in.next();

直接使用扫描器,进行控制台输入数据的读入。那么就可以对人的手势进行一个初始化的赋值行为了。

2.电脑手势

那么接下来我们来想想电脑的手势如何进行一个赋值的?我们知道电脑是不能直接产生这些我们所需要的手势数据的,那么我们知道电脑能进行随机数的产生,那么我们是否可以借助随机数的产生,然后进行我们数据的转换输出呢?很明显,这个构思也是可行的。那么我们需要什么呢?首先必不可缺的一定是随机数的使用,那么我们可能还需要数组进行数据的存放。那么我们接下来应该怎么样进行 *** 作呢?
请看看我下面的代码吧!

public String[] computerGuesture = new String[]{"stone","scissors","cloth"};
Random random = new Random(3);
int computerRandom = random.nextInt(3);
String getGomputerGuesture = compuerGuesture[computerRandom];

那么我们电脑的手势赋值 *** 作就完成了。

3.判断 *** 作

那么我们下面就要进行一个判断 *** 作。那么我们就需要就需要进行一个judge函数的编写。那么我们首先要想这个判断 *** 作是属于谁的?参数是什么?这两个问题是我们编写judge函数最主要思考问题的方向。
我们知道参数分别是人和电脑输入地手势数据。那么这个判断 *** 作应该是不属于我们人和电脑类中的任意一个类的,那我们应该重新创建一个类,这个类名为我们gameJudge类, 那么我们这个类应该存放judge方法的那么我们接下来就写写这个函数应该是怎么样写的。

/**
     *@Description: 判断游戏输赢的方法
     *@Param: [personGuesture, computerGuesture]
     *@return:[java.lang.String, java.lang.String]
     *@Author: Mr.Lin
     *@Date: 2022/5/11 14:45
     */
    public String judge(String personGuesture  ,  String computerGuesture){
       String gameReuslt = null;
        switch (personGuesture){
            case "stone":
                if (personGuesture == computerGuesture)gameReuslt = "平局";
                else if (computerGuesture == "sciccors")gameReuslt = "胜利";
                else if (computerGuesture == "cloth")gameReuslt = "失败";
                break;
            case "sciccors":
                if (personGuesture == computerGuesture)gameReuslt = "平局";
                else if (computerGuesture == "cloth")gameReuslt = "胜利";
                else if (computerGuesture == "stone")gameReuslt = "失败";
                break;
            case "cloth":
                if (personGuesture == computerGuesture)gameReuslt = "平局";
                else if (computerGuesture == "stone")gameReuslt = "胜利";
                else if (computerGuesture == "sciccors")gameReuslt = "失败";
                break;
        }
        return gameReuslt;
    } 

我们对于判断函数是否是某一个动作时候,首先会想到的就是“==”的判断函数,一切看起来都是理所当然,我们这个时候就可以将我们的代码放入主函数进行一个使用,看看是否结果如我们所想一样。

4.错误的地方

我们可以进行一个调试 *** 作,我们会发现我们的进行判断 *** 作时候,我们会发现在判断 *** 作时候我们的判断 *** 作不如我们所想一样,那么应该如何进行字符串的判断相等 *** 作呢?

1.equal方法

Java给我们提供一个我们一个用于判断字符串相等的方法叫作equal(),它区别于我们平常使用的“==”的符号,双等号主要的作用是用于判断两个变量的地址是否相同。而equal方法可以忽略判断地址,直接去判断字符串内容是否相等。所以我们可以将我们的判断 *** 作中使用双等号的地方进行修改,将其改为equal方法,再进行一个运行。
对这个方法更为之具体的了解可以看看我这篇文章:Java的equals方法的一些理解

二、项目改良方向 1.判断方法

我们首先想想我们判断方法是一个是什么样的东西?
这应该是我们实现我们的游戏机制的一个方法,那么我们想想我们机制方法是不是应该可以放入一个类,声明方法的话我们放入另外一个类中,那么在团队协作中,我们就可以不去过于关注方法的本身,仅仅只需要知道某个方法,它的具体 *** 作有什么用途,就可以直接去调用。
那么我们就可以引出接口的概念。

1.接口

首先接口的关键词是interface,接口的定义,在《Java核心技术1》中对接口的描述是,接口不是类,而是对类的一组需求描述,这些类要遵循接口描述的统一格式进行定义。从描述中来看,接口是一种规范,它要求我们中要写方法将名字和参数都需要相同。那么我们就会有另外一个问题出现,接口中仅有方法名的方法进行一个方法完善的编写这个行为应该发生在哪里呢?这个就牵扯到实现类的概念了。

2.实现类

实现关键词是implements,在代码中通常这样来定义的一个接口的实现类。

public class IMPH implements interfaceName

当我们写完这个实现类的时候,idea会对我们我们的实现类增加一条下划线,我们使用alt+enter进行查看的时候,它就会提醒我们要对它进行一个方法的实现的 *** 作。这个就能解决我们的方法实现问题。

3.判断方法的升级

我们会发现我们进行的判断方法会用大量的代码重现,如果希望减少代码的重现的,降低代码的多次使用,我们就需要进行一个算法的升级,我们可以用数字来代替字符串的输入。
具体我们可以看看这篇文章
l算法进化历程1剪刀石头布
那么通过这篇文章我们就可以进行判断方法升级,我这里就假设 0为石头,1为剪刀,2为布,那么我们就可以得到以下的代码块。

public String judge(int computerGuesture,int personGesture){
        int end = personGesture-computerGuesture;
        String result = null;
        if (end == 0) result = "平局";
        else if (end == 1 || end == -2) result = "失败";
        else if (end == -1 || end == 2) result = "胜利";
        return result;
    }
1.用户的升级

首先我们在石头剪刀布的小游戏中,我们有两个类——人类和电脑类两个类,我们会发现两个类中有相同的地方,名字和id甚至是手势都是两个类相同的成员变量,唯一不同的是我们手势的获取不同。那么有相同的成员变量还有不相同的方法,我们就可以使用抽象类来进行我们代码的升级。

1.抽象类

首先抽象类的关键词是abstract,我们仅需在类名之前加入abstract关键字,那么这个类就是抽象类。我们来看看在《Java核心卷一》的描述,如果自下而上在类的继承层次结构中上移,位于上层的类更具有通用信不过,甚至可能更加抽象,从描述中我们会发现抽象最大特点就是在于其通用性,那么对于有着共性的两个类是不是可以在抽象类中归纳的属性,然后通过归纳性的减少代码的重复编写。显然这种方案是切实可行的。

2.抽象方法

上面我们归纳了共同的点,那么对于不同的方法,我们应该如何进行方法的重载呢?

1.方法重载与方法重写的区别
  1. 首先我们先来了解下什么是方法重载?
    方法重载主要是在抽象类和接口中使用,就比如我们在定义方法是抽象的,那么我们就需要在子类中进行一个方法的重载,这时候我们写一个子类去继承当前我们命名的抽象类,那么这个时候,idea就会提醒我们需要进行一个方法的重载,方法的重载是有关键字==@Override==,不过这个关键字是idea自己给我们增加上去的,我们就不需要进行自己手动的书写,这个关键字的作用可以让我们判断当前的方法是否是重载的方法,如果我们不是进行着方法的重写的话,这个关键字就会自行报错。
  2. 方法重写又是什么呢?
    对于相同类型的业务,但是方法参数不同,这时候就需要用到我们的方法重写,举个简单的例子,就是print方法,我们会发现联想框中会有多种的参数,有int,float,String…等类型的参数。
  3. 相同点与区别?
    首先是相同点,方法名都需要相同;
    1. 区别:方法重写的参数可以不同,返回值也可以不同;
    2. 使用逻辑上,方法重载是由于需要是实现接口,实现抽象方法;方法重写是由于相似的业务场景,相同的命名可以便于使用者更好了解方法的用途。
2.抽象方法的重载 1.人类
@Override
    public int getGuesture(int input) {
        return this.guesture = input;
    }
2.电脑类
 @Override
    public int getGuesture(int input) {
        return this.guesture = input;
    }
3.接口方法重载
@Override
    public String judge(int computerGuesture, int personGuesture) {
        int end = personGuesture-computerGuesture;
        String result = null;
        if (end == 0) result = "平局";
        else if (end == 1 || end == -2) result = "失败";
        else if (end == -1 || end == 2) result = "胜利";
        return result;
3.具体代码的实现 1.User类

抽象类的代码编写:

/**
 * @program:IntelliJ IDEA
 * @Description:利用抽象类
 * @author:Mr.CheCheHuiBujianO
 * @data: 2022/4/29 11:03
 */
public abstract class User {
    private String name;
    private String id;
    public int guesture;

    public User(String name, String id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public abstract int getGuesture(int input);
}
2.人和电脑类
/**
 * @program:IntelliJ IDEA
 * @Description:继承User类
 * @author:Mr.CheCheHuiBujianO
 * @data: 2022/4/29 11:08
 */
public class Person extends User{

    public Person(String name, String id) {
        super(name, id);
    }

    @Override
    public int getGuesture(int input) {
        return this.guesture = input;
    }
}
/**
 * @program:IntelliJ IDEA
 * @Description:继承Ures类
 * @author:Mr.CheCheHuiBujianO
 * @data: 2022/4/29 11:10
 */
public class Computer extends User{
    public Computer(String name, String id) {
        super(name, id);
    }

    @Override
    public int getGuesture(int input) {
        return this.guesture = input;
    }
}
3.接口以及实现类

接口

public interface Judge {
    String judge(int computerGuesture,int personGuesture);
}

实现类

/**
 * @program:IntelliJ IDEA
 * @Description:实现Judge接口
 * @author:Mr.CheCheHuiBujianO
 * @data: 2022/4/29 11:13
 */
public class JudgeIMPH implements Judge{

    @Override
    public String judge(int computerGuesture, int personGuesture) {
        int end = personGuesture-computerGuesture;
        String result = null;
        if (end == 0) result = "平局";
        else if (end == 1 || end == -2) result = "失败";
        else if (end == -1 || end == 2) result = "胜利";
        return result;
    }
}
4.main函数
import lombok.extern.slf4j.Slf4j;
import version1_0.GameJudge;

import java.util.Random;
import java.util.Scanner;

/**
 * @program:IntelliJ IDEA
 * @Description:游戏的主函数,使用日志框架输出
 * @author:Mr.CheCheHuiBujianO
 * @data: 2022/4/29 11:16
 */
@Slf4j
public class GameMain {
    public static void main(String[] args) {
        Person person1 = new Person("张三","003");
        Computer computer1 = new Computer("阿法狗","007");
        log.info("请输入你要选择的手势(0,石头,1,剪刀,2布):");
        Scanner in = new Scanner(System.in);
        Random random = new Random(3);

        //利用接口实现类
        JudgeIMPH judgeIMPH = new JudgeIMPH();
        int count = 0,win = 0,debeat = 0;
        while(count <= 5 && win <=3 && debeat <= 3){
            //使用person1.guesture接人输入
            person1.guesture = in.nextInt();
            //使用end来接judge方法的返回值
            String end = judgeIMPH.judge(computer1.getGuesture(random.nextInt()), person1.getGuesture(person1.guesture));
            if (end.equals("胜利"))win++;
            else if (end.equals("失败"))debeat++;
            count++;
            log.info("现在游戏已经进行"+count+",其中胜利了"+win+",失败了"+debeat);
        }
    }
}

这个中间使用了日志输出的方法,如果没有用maven构建项目的话,可以将log.info()改为System.out.print()来输出数据。


总结

这一章节主要学习了抽象类,接口,方法重载和方法重写还有在石头剪刀布中算法对于简化代码的作用,还有介绍了Java常用API的equal方法的使用。
这一次编写程序还没完善的问题就是在如果用户在控制台中输入超过2的数字会造成程序的直接终止;还有是否可以将这个程序变为一个子线程的提升空间;
这一次编写中,最大的挑战是理解接口和抽象类在我们程序中具体充当的角色,是从一个这么样的方面去思考?最后我选择在人文伦理上,理解抽象类和接口的区别,在下一章节的编写,我会从人文伦理的角度去对接口和抽象类在程序中应该充当的角色进行一个解释。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/924385.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存