我的世界Java设置白天
java城堡游戏续
- 城堡游戏最终版(增加了操作指令(如go bye help)的扩展性)
- 主要思路:
- 代码
- MyGame(主类)
- MyRoom类
- Handler类(父类)
- HandlerGo类(执行go这个命令的类)
- HandlerBye类(执行Bye这个命令的类)
- HandlerHelp类(执行help这个命令的类)
- 如何扩展
- 总结
- 学习中的问题
上次的问题这次大概有了一些解决
硬编码:运行时不能改变
软编码:运行时能够改变
主要体现在哈希表能添加对应的key与value
城堡游戏最终版(增加了操作指令(如go bye help)的扩展性)
主要思路:
上次说的对应关系可以用哈希表软编码,这里的对应关系是方向对应的房间。
于是我们就增加了房间的扩展性 这次是操作指令对应要执行的命令,
相应的我们就增加了操作指令的扩展性
用哈希表来使得操作指令与函数对应,但是哈希表里面的值只能是对象,不能是函数。
但是类里面含有函数,只需要让一个操作指令对应一个类,这样get(操作指令)得到的就是不同的类,让这些类里面共有一个函数docmd(进行操作的函数)【共有函数用继承】
只需要再定义一个父类的对象,就可以用相同的函数名执行不同的操作
代码
MyGame(主类)
import java.util.*; public class MyGame { static Scanner in = new Scanner(System.in); private MyRoom curroom; private HashMap<String,Handler> handlers = new HashMap<String,Handler>(); public void CreatRoom() { //制造房间 MyRoom outside,bedroom,bathroom,livingroom,diningroom,kitchen; outside = new MyRoom("外面"); bedroom = new MyRoom("卧室"); livingroom = new MyRoom("客厅"); diningroom = new MyRoom("餐厅"); kitchen = new MyRoom("厨房"); bathroom = new MyRoom("浴室"); curroom = outside; //制造周围的房间 // bed //地图:->living bath // din // kitchen outside.SetRound("east",livingroom); livingroom.SetRound("north",bedroom); livingroom.SetRound("south",diningroom); livingroom.SetRound("west", outside); livingroom.SetRound("east", bathroom); bedroom.SetRound("south", livingroom); diningroom.SetRound("north",livingroom); diningroom.SetRound("south",kitchen); kitchen.SetRound("north",diningroom); bathroom.SetRound("west",livingroom); bathroom.SetRound("up", livingroom); livingroom.SetRound("down", bathroom); /*扩展了各种方向,现在扩展命令》 因为哈希表不能传入函数,只能传入对象,所以能传入类,而类里面有函数, 后面再定义一个类,让它等于哈希表里面的对应命令的类,然后使用该类的函数就ok*/ } public void Printstart() { System.out.println("欢迎来到三三与然然的家!(可以输入help寻求帮助)"); handlers.put("go",new HandlerGo(this));//如果没有继承,会报错因为是Handler为值, handlers.put("help", new HandlerHelp(this)); handlers.put("bye", new HandlerBye(this)); CreatRoom(); } public void Printcurroom() { System.out.println("你在: "+curroom);//curroom是MyRoom类 System.out.print("出口有: "); System.out.println(curroom.GetExit()); //System.out.println(); } public void play() { String[] words = new String[3]; String line,value; Handler handler = new Handler(this);//这是哈希表里的handler类 while(true) { value=""; line=in.nextLine(); words = line.split(" "); handler=handlers.get(words[0]);//得到go bye等命令以确定handler的类型 if(words.length>1) value=words[1]; if(handler!=null) { handler.docmd(value); if(handler.isBye()) break; } } } public void GoRoom(String direction) { MyRoom nextroom=null; nextroom=curroom.GetRound(direction);//一个返回room的函数,查看direction方向有没有房间 if(nextroom==null) System.out.println("这里没有门!"); else curroom=nextroom; } public static void main(String[] args) { MyGame game = new MyGame(); game.Printstart(); game.Printcurroom(); game.play(); } }MyRoom类
import java.util.*; public class MyRoom { private String description; private HashMap<String,MyRoom> exit = new HashMap<String,MyRoom>(); //private MyRoom northroom,southroom,westroom,eastroom;//设置一个房间的东南西北的房间; MyRoom(String description)//构造函数,对房间命名; { this.description=description; } public void SetRound(String dir,MyRoom room) { exit.put(dir, room);//设置方向和房间; } public MyRoom GetRound(String direction) { return exit.get(direction); } public String GetExit() { StringBuffer set = new StringBuffer(); for(String dir : exit.keySet()) { set.append(dir); set.append(" "); }//将hash表的key付给set; return set.toString(); } public String toString()//description是MyRoom类里面的String { return description; } }Handler类(父类)
public class Handler { protected MyGame room; public Handler(MyGame room) { this.room=room; } public void docmd(String cmd) { } public boolean isBye() { return false; } }HandlerGo类(执行go这个命令的类)
public class HandlerGo extends Handler{ public HandlerGo(MyGame room) { super(room); } public void docmd(String cmd) { room.GoRoom(cmd); room.Printcurroom(); } }HandlerBye类(执行Bye这个命令的类)
public class HandlerBye extends Handler { public boolean isBye() { System.out.println("欢迎下次再来,再见!"); return true; } public HandlerBye(MyGame room) { super(room); } }HandlerHelp类(执行help这个命令的类)
public class HandlerHelp extends Handler { public HandlerHelp(MyGame room) { super(room); } public void docmd(String cmd) { System.out.print("迷路了吗?你可以做的命令有:go bye help"); System.out.println("如:\tgo east"); } }如何扩展
在这里要增加新的命令
只需要加一个哈希表,key为命令,value为操作的类
再新建一个操作的类就可以了
这样的话,代码其他地方需要改的除了多一个哈希表,就没有了。
总结
是对昨天城堡游戏哈希表以及扩展性的衍生,更加体会到了可扩展性的作用。联想到了是不是还可以加上更多其他的东西来衍生。
哈希表的值只能是对象
学习中的问题
HanderGo类里面的cmd操作是用的主类里面的函数,而要用这个函数,我们就的有一个主类的对象。
所以我们在父类里面创建了一个构造函数,将主类的对象传过来
这样的话子类也得添加一个构造函数,十分麻烦。
有没有其他的办法能在不添加构造函数的情况下完成这个目的呢?
这里父类的成员变量定义是protected
这个是啥意思,为什么不能用public??