欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

荐 读一个Java无聊的代码,居然收获太多!

程序员文章站 2022-03-29 17:26:41
这个代码虽然很无聊, 但是我觉得他可以包括java基础的所有知识点。 一定要看下去学习。...

Java: 从入门到入土, 真的是这样的吗? 最近整理了一期视频教学素材,把学习到的知识点陈列如下:

荐
                                                        读一个Java无聊的代码,居然收获太多!


我们都知道在java中, 他的设计风格万物皆是对象,不同于其他语言,java更加灵活多变, 这也是它独特的地方,为此,做一个一个E-R图, 方便学习。

ER图:

荐
                                                        读一个Java无聊的代码,居然收获太多!

正文:

这个代码虽然很无聊, 但是我觉得他可以包括java入门的所有知识点。 一定要看下去学习。

整体package:

荐
                                                        读一个Java无聊的代码,居然收获太多!

从这个图可以看得出来, 这有很多文件, 每个文件对应着一个对象。从Game对象开始学习。

在Game类中:

package castle;

import java.util.HashMap;
import java.util.Scanner;

public class Game {
    private Room currentRoom;  私有 room  成员属性
    private HashMap<String, Handle> handles = new HashMap<String, Handle>();  私有 hashmap 容器

    public Game() {  构造函数
        createRooms();
        handles.put("bye", new HandleByes(this));
        handles.put("help", new HandleHelp(this));
        handles.put("go", new HandleGo(this));
    }
	// 下面都是通过生成的Room对象 进行成员方法的操作
    private void createRooms() {
        Room outside, lobby, pub, study, bedroom, godroom;

        //	制造房间
        outside = new Room("城堡外");
        lobby = new Room("大堂");
        pub = new Room("小酒吧");
        study = new Room("书房");
        bedroom = new Room("卧室");
        godroom = new Room("藏宝室");

        //	初始化房间的出口
        outside.setExit("upper", lobby);
        lobby.setExit("right", pub);
        lobby.setExit("left", study);
        pub.setExit("right", outside);
        pub.setExit("left", pub);
        study.setExit("upper", bedroom);
        bedroom.setExit("upper", godroom);
        currentRoom = outside;  //	从城堡门外开始
    }



    // 以下为用户命令

    public void goRoom(String direction) {
        Room nextRoom = currentRoom.getExit(direction);
        if (nextRoom == null) {
            System.out.println("那里没有门!");
        } else {
            currentRoom = nextRoom;
            printFun();
        }
    }

    public void play() {
        Scanner in = new Scanner(System.in);
        while (true) {
            String line = in.nextLine();
            String[] words = line.split(" ");
            Handle handle = handles.get(words[0]);
            String values = "";
            if (words.length > 1) {
                values = words[1];
            }

            if (handle != null) {
                handle.cmdDir(values);
                if (handle.isByes()) {
                    break;
                }
            }

        }
        in.close();  关闭输入
        System.out.println("感谢您的光临。再见!");

    }

    public void printWelcome() {

        System.out.println("\n" + "欢迎来到城堡!" +
                "这是一个超级无聊的游戏。" +
                "如果需要帮助,请输入 'help' 。");
        printFun();
    }

    public void printFun() {
        System.out.println("现在你在" + currentRoom);
        if ("藏宝室".equals(currentRoom.toString())) {
            System.out.println("恭喜你发现了" + currentRoom);
        }
        System.out.println("出口有:" +
                currentRoom.getExitDirection());
    }
    public static void main(String[] args) {
        Game game = new Game();  // 生成对象
        game.printWelcome();  //fun
        game.play();     //fun
    }

}

这是翁老师的一个视频教程, 刚看完的一刻, 我是很懵逼的, 完全不知道在这个函数内, 为什么会出现二个对象, 一个game 一个room , 以及他们怎么调用, 之间的关系又是怎么样的, 这在我后面的自己读代码过程中, 明白了。

实际上, 因为他们在一个package中, 而且他们的类初始化都是public类型, 所以在文件中调用都是合法的, 只有private类型 其他类中不能访问,
在这个game中, 生成了很多room对象, 然后分别给他们设置房间出口, 也就是设置 hashmap的键和值, 这个方法是room类中的方法,

关于Room类中:

package castle;

import java.util.HashMap;

public class Room {
    private String description;
    //  生成一个hashmap 容器, 用来存放方向和房间
    private HashMap<String, Room> exit = new HashMap<String, Room>();

    public Room(String description) {
        this.description = description;
    }

    public void setExit(String direction, Room room) {
        // 设置出口 哈希表
        exit.put(direction, room);
    }


    @Override
    public String toString() {
        return description;
    }

    public Room getExit(String direction) {
        // 根据位置 返回可以到达的地点
        return exit.get(direction);
    }

    public String getExitDirection() {
        // StringBuffer 减少内存的使用情况
        // string 修改字符串会不断的增加新的字符串 增加内存的开销
        StringBuffer SB = new StringBuffer();
        for (String dir : exit.keySet()) {
            SB.append(dir + " ");
        }
        return SB.toString();
    }


}

这里要注意的一点, 也就是字符串,在java中, 如果每次对字符串进行修改,内存中会不断的生成新的字符串去替换它, 所以每次操作,都会对内存的增加一定的负担, 所以要避免发生, 使用 StringBuffer 作为字符串的类修饰, 就可以避免这个问题。

在handle类中:

package castle;

public class Handle {
    protected Game game;
    public Handle(Game game){
        this.game = game;
    }
    public void cmdDir(String word){}
    public boolean isByes(){return false;}
}



class HandleByes extends  Handle{
    public HandleByes(Game game) {
        super(game);
    }

    @Override
    public boolean isByes() {
        return true;
    }
}



class HandleHelp extends Handle{
    public HandleHelp(Game game) {
        super(game);
    }

    @Override
    public void cmdDir(String word) {

//        super.cmdDir(word); 优先父类方法
        System.out.println("迷路了吗?你可以做的命令有:go bye help");
        System.out.println("如:\tgo down");
    }
}


class HandleGo extends Handle{
    public HandleGo(Game game) {
        super(game);
    }

    @Override
    public void cmdDir(String word) {
        game.goRoom(word);
    }
}

在继承中, 如果我们要改写父类的方法, 需要删除super() 这个关键词, 否则这样继承,就是优先使用父类方法,

后记:

关于java, 我还是个菜鸡, 还在学习中, 请勿喷,欢迎指教!

本文地址:https://blog.csdn.net/qq_45906219/article/details/107227293