南昌航空大学实验报告
2021 年 11 月 12 日
课程名称:面向对象程序设计B 实验名称: 农夫过河之继承与多态
学号: 姓名: 同组人:
指导教师评定: 签名:
一、实验目的
1、 掌握Java语言中多态的基本概念及使用方法;
2、 掌握上转型和下转型的基本概念及使用方法;
3、 掌握Object类中的toString()、equals()的使用方法;
4、 掌握instanceOf运算符的使用方法;
5、 掌握Java语言中成员变量隐藏的基本概念及使用方法;
二、实验要求
1、 根据实验步骤中提出的要求,使用eclipse等开发工具编写相应的Java程序;
2、 编译、运行自己所编写的Java程序;
3、 根据编译与运行过程中所获得的错误信息修改程序直至获得正确的结果;
4、 记录实验中遇到的各类问题并以及解决办法。
三、实验步骤
实验三(1)实验步骤
1、 农夫过河问题:将之前的代码进行如下改进:
(1) 为之前的类添加合适的父类。
(2) 为父类添加适合的属性和方法。并以此为基础修改原有的类,使之与添加的类构成继承关系。
(3) 使用多态改进整个代码,提高代码的复用性。
如附录中的代码所示,添加了object作为农夫,羊,狼,白菜的父类,具体的请看第二步的类图。
2、 请画出完整类图,包含每个类的类名、属性、方法以及类与类的关联,并用文字说明关联类的关联关系。
类图如下:
3、 说明你设计的继承关系的理由,为什么不用组合
因为setcrossriver()方法,eat()方法,sethascross()方法都能用到,并且继承和组合都是面向对象中代码复用的方式,父类的内部细节对子类可见,但是在组合当中,对象之间的内部细节不可见。更重要的是继承强调的是is-a的关系,组合强调的是has-a的关系。在这里我觉得继承更为恰当。
实验三(2)实验步骤
4、 农夫过河问题,将之前的代码进行如下改进:
(1) 修改程序代码,在游戏中增加胡萝卜、兔子两个角色,过河的规则改为一次可以带两样东西过河。
具体改进请看代码。代码在附录。
5、 请画出完整类图,包含每个类的类名、属性、方法以及类与类的关联,并用文字说明关联类的关联关系
Object是抽象类作为父类,里面的方法有是否过河,是否存活,是否上船,以及判断是否吃的方法。
而rabbit,wolf,farmer,carrot,cabbage则作为子类继承父类的方法与属性。
GameGui是界面类,Game是游戏具体执行类
这两个类大体和之前一样无变动。
6、 实现第一步的功能时,你的代码做了哪些修改。如何避免修改原有代码?
首先是增加了carrot类和rabbit类,同时改动了界面的显示,也就是GameGui类进行改动增加了几个显示。也改变了wolf类和sheep类里面eat这各方法,都增加了一种可被吃食物的判断。最后则是对Game类这个游戏具体执行的地方加上rabbit和carrot行动方式。
如何避免代码的修改:主要还是要看类是如和划分的,它们的耦合性如何,关联性强不强,像我的代码整体耦合性还是比较低的改动起来还是蛮方便的,改动的话大部分都是添加类和添加方法,改动方面就改动了两个极小的地方(也就是eat方法里面多了一个选择判断)。
7、 修改系统功能,运行程序后,用户可以选择玩新规则(五个角色、一次两样东西带过河)或者老规则(三个角色、一次一样东西带过河)的游戏。
具体实现看代码。代码在附录。
四、实验结果
运行结果如下:
选择模式(满足实验要求1和4):
若选1:(在这里就给出成功和失败的截图)
失败;
成功:
若选2:
失败:
成功:
五、实验小结
这个实验是分为两个课时的,第一节课是完成将以前的农夫过河问题用到继承来实现,第二节课则是添加了两个新类同时游戏规则也稍稍改变,整体实验说不上难,主要就是看考虑的周到不周到,我新增了两个子类后最开始因为没设置好过河之后对它们位置和是否在船上的变动,导致农夫独自过河的时候,狼羊白菜和胡萝卜都没事,这就很明显存在问题。最后说一下通过实验的收获,通过实验更为熟练的掌握equals()的用法,类的继承多态,这些老师上课讲过,pta也练过,这次的实验无非是把它们融合在一起运用罢了,但是也锻炼巩固了我们所学会的东西,同时这实验的开放性也高有什么样的想法都可以自己去尝试,提高了我们对所学知识运用的熟练度。当然这次的代码我感觉还有很大的改善空间,比如说进一步降低代码的耦合性,进而让减轻更改时的复杂性。
六、附录
代码:
package 农夫过河;
public class Cabbage extends object{
public void showStatus() {
System.out.println("cabbage is alive :"+isAlive+" cabbage has Cross :"+hasCross);
}
}
package 农夫过河;
public class Carrot extends object{
public void showStatus() {
System.out.println("carrot is alive :"+isAlive+" carrot has Cross :"+hasCross);
}
}
package 农夫过河;
public class Farmer extends object{
public void showStatus() {
System.out.println("Farmer has Cross :"+hasCross);
}
}
package 农夫过河;
import java.util.Scanner;
public class Game {
Wolf wolf;
Sheep sheep;
Cabbage cabbage;
Farmer farmer;
GameGui GameGui;
Rabbit rabbit;
Carrot carrot;
Game() {
wolf = new Wolf();
sheep = new Sheep();
cabbage = new Cabbage();
farmer = new Farmer();
rabbit = new Rabbit();
carrot = new Carrot();
GameGui=new GameGui();
}
protected void play(){
Scanner input = new Scanner(System.in);
int choice = 0,choice1 = 0; //用户输入选择
boolean gameOver=false,//游戏结束标志,默认为false,代表游戏进行中,未结束
win=false; //游戏输赢标志,默认为false,代表未赢得游戏。
System.out.println("请选择模式1.旧规则 2.新规则");
choice = input.nextInt();
while(!gameOver)
{
GameGui.menu(choice);
choice1 = input.nextInt();
switch(choice1)
{
case 0:
break;
case 1:/* 农夫独自过河的处理 */
farmer.setcrossRiver(!farmer.getcrossRiver());
break;
case 2:/* 农夫带狼的处理 */
if(farmer.gethasCross()==wolf.gethasCross()) {
farmer.setcrossRiver(!farmer.getcrossRiver());
wolf.setcrossRiver(!wolf.getcrossRiver());
}
else
System.out.println("操作错误,请选择有效操作!");
break;
case 3:/* 农夫带羊的处理 */
if(farmer.gethasCross()==sheep.gethasCross()) {
farmer.setcrossRiver(!farmer.getcrossRiver());
sheep.setcrossRiver(!sheep.getcrossRiver());
}
else
System.out.println("操作错误,请选择有效操作!");
break;
case 4:/* 农夫带白菜的处理 */
if(farmer.gethasCross()==cabbage.gethasCross()) {
farmer.setcrossRiver(!farmer.getcrossRiver());
cabbage.setcrossRiver(!cabbage.getcrossRiver());
}
else
System.out.println("操作错误,请选择有效操作!");
break;
case 5:/* 农夫带兔子的处理 */
if(choice == 2) {
if(farmer.gethasCross()==rabbit.gethasCross()) {
farmer.setcrossRiver(!farmer.getcrossRiver());
rabbit.setcrossRiver(!rabbit.getcrossRiver());
}
else
System.out.println("操作错误,请选择有效操作!");
}
else
System.out.println("请输入范围内的值");
break;
case 6:/* 农夫带胡萝卜的处理 */
if(choice == 2) {
if(farmer.gethasCross()==carrot.gethasCross()) {
farmer.setcrossRiver(!farmer.getcrossRiver());
carrot.setcrossRiver(!carrot.getcrossRiver());
}
else
System.out.println("操作错误,请选择有效操作!");
}
else
System.out.println("请输入范围内的值");
break;
case 7:/* 农夫带狼和兔子的处理 */
if(choice == 2) {
if(farmer.gethasCross()==wolf.gethasCross()&&farmer.gethasCross()==rabbit.gethasCross()) {
farmer.setcrossRiver(!farmer.getcrossRiver());
wolf.setcrossRiver(!wolf.getcrossRiver());
rabbit.setcrossRiver(!rabbit.getcrossRiver());
}
else
System.out.println("操作错误,请选择有效操作!");
}
else
System.out.println("请输入范围内的值");
break;
case 8:/* 农夫带狼和羊的处理 */
if(choice == 2) {
if(farmer.gethasCross()==wolf.gethasCross()&&farmer.gethasCross()==sheep.gethasCross()) {
farmer.setcrossRiver(!farmer.getcrossRiver());
wolf.setcrossRiver(!wolf.getcrossRiver());
sheep.setcrossRiver(!sheep.getcrossRiver());
}
else
System.out.println("操作错误,请选择有效操作!");
}
else
System.out.println("请输入范围内的值");
break;
case 9:/* 农夫带狼和白菜的处理 */
if(choice == 2) {
if(farmer.gethasCross()==wolf.gethasCross()&&farmer.gethasCross()==cabbage.gethasCross()) {
farmer.setcrossRiver(!farmer.getcrossRiver());
wolf.setcrossRiver(!wolf.getcrossRiver());
cabbage.setcrossRiver(!cabbage.getcrossRiver());
}
else
System.out.println("操作错误,请选择有效操作!");
}
else
System.out.println("请输入范围内的值");
break;
case 10:/* 农夫带狼和胡萝卜的处理 */
if(choice == 2) {
if(farmer.gethasCross()==wolf.gethasCross()&&farmer.gethasCross()==carrot.gethasCross()) {
farmer.setcrossRiver(!farmer.getcrossRiver());
wolf.setcrossRiver(!wolf.getcrossRiver());
carrot.setcrossRiver(!carrot.getcrossRiver());
}
else
System.out.println("操作错误,请选择有效操作!");
}
else
System.out.println("请输入范围内的值");
break;
case 11:/* 农夫带羊和兔子的处理 */
if(choice == 2) {
if(farmer.gethasCross()==sheep.gethasCross()&&farmer.gethasCross()==rabbit.gethasCross()) {
farmer.setcrossRiver(!farmer.getcrossRiver());
sheep.setcrossRiver(!sheep.getcrossRiver());
rabbit.setcrossRiver(!rabbit.getcrossRiver());
}
else
System.out.println("操作错误,请选择有效操作!");
}
else
System.out.println("请输入范围内的值");
break;
case 12:/* 农夫带羊和白菜的处理 */
if(choice == 2) {
if(farmer.gethasCross()==sheep.gethasCross()&&farmer.gethasCross()==cabbage.gethasCross()) {
farmer.setcrossRiver(!farmer.getcrossRiver());
sheep.setcrossRiver(!sheep.getcrossRiver());
cabbage.setcrossRiver(!cabbage.getcrossRiver());
}
else
System.out.println("操作错误,请选择有效操作!");
}
else
System.out.println("请输入范围内的值");
break;
case 13:/* 农夫带羊和胡萝卜的处理 */
if(choice == 2) {
if(farmer.gethasCross()==sheep.gethasCross()&&farmer.gethasCross()==carrot.gethasCross()) {
farmer.setcrossRiver(!farmer.getcrossRiver());
sheep.setcrossRiver(!sheep.getcrossRiver());
carrot.setcrossRiver(!carrot.getcrossRiver());
}
else
System.out.println("操作错误,请选择有效操作!");
}
else
System.out.println("请输入范围内的值");
break;
case 14:/* 农夫带兔子和白菜的处理 */
if(choice == 2) {
if(farmer.gethasCross()==rabbit.gethasCross()&&farmer.gethasCross()==cabbage.gethasCross()) {
farmer.setcrossRiver(!farmer.getcrossRiver());
rabbit.setcrossRiver(!rabbit.getcrossRiver());
cabbage.setcrossRiver(!cabbage.getcrossRiver());
}
else
System.out.println("操作错误,请选择有效操作!");
}
else
System.out.println("请输入范围内的值");
break;
case 15:/* 农夫带兔子和胡萝卜的处理 */
if(choice == 2) {
if(farmer.gethasCross()==rabbit.gethasCross()&&farmer.gethasCross()==carrot.gethasCross()) {
farmer.setcrossRiver(!farmer.getcrossRiver());
rabbit.setcrossRiver(!rabbit.getcrossRiver());
carrot.setcrossRiver(!carrot.getcrossRiver());
}
else
System.out.println("操作错误,请选择有效操作!");
}
else
System.out.println("请输入范围内的值");
break;
case 16:/* 农夫带胡萝卜和白菜的处理 */
if(choice == 2) {
if(farmer.gethasCross()==carrot.gethasCross()&&farmer.gethasCross()==cabbage.gethasCross()) {
farmer.setcrossRiver(!farmer.getcrossRiver());
carrot.setcrossRiver(!carrot.getcrossRiver());
cabbage.setcrossRiver(!cabbage.getcrossRiver());
}
else
System.out.println("操作错误,请选择有效操作!");
}
else
System.out.println("请输入范围内的值");
break;
default: System.out.println("请输入范围内的值");
}
if(farmer.getcrossRiver()) {
farmer.setcrossRiver(!farmer.getcrossRiver());
farmer.sethasCross(!farmer.gethasCross());}
if(sheep.getcrossRiver())
{
sheep.setcrossRiver(!sheep.getcrossRiver());
sheep.sethasCross(!sheep.gethasCross());
}
if(wolf.getcrossRiver())
{
wolf.setcrossRiver(!wolf.getcrossRiver());
wolf.sethasCross(!wolf.gethasCross());
}
if(cabbage.getcrossRiver())
{
cabbage.setcrossRiver(!cabbage.getcrossRiver());
cabbage.sethasCross(!cabbage.gethasCross());
}
if(choice==2)
{
if(carrot.getcrossRiver())
{
carrot.setcrossRiver(!carrot.getcrossRiver());
carrot.sethasCross(!carrot.gethasCross());
}
if(rabbit.getcrossRiver())
{
rabbit.setcrossRiver(!rabbit.getcrossRiver());
rabbit.sethasCross(!rabbit.gethasCross());
}
rabbit.eatCabbageandCarrot(cabbage,farmer,carrot,choice);//兔子吃白菜和胡萝卜
}
wolf.eatSheepandRabbit(sheep,farmer,rabbit,choice);//狼吃羊和兔子,如果羊不在同一边,则吃不到,如果在同一边,羊被吃
sheep.eatCabbageandCarrot(cabbage,farmer,carrot,choice);//同上
GameGui.showStatus(farmer,wolf,sheep,cabbage,rabbit,carrot,choice);
if(choice1==0)
gameOver=true;
else
gameOver = isGameOver(choice);
}
win=this.hasWin(choice);
if(win) {
System.out.println("game over: you win !");
}else {
System.out.println("game over: you lose !");
}
input.close();
}
/*
* 判断游戏是否结束
* 输入:无
* 运算:羊、白菜任一实体被吃,游戏结束,或者狼、羊、白菜均未被吃且全部渡过河,游戏结束
* 输出:游戏结束--返回true ,未结束--返回false
*/
public boolean isGameOver(int choice) {
if(sheep.getisAlive()==false||cabbage.getisAlive()==false||rabbit.getisAlive()==false||carrot.getisAlive()==false) {
return true;
}
if(wolf.gethasCross()&&sheep.gethasCross()&&cabbage.gethasCross()) {
return true;
}
if(choice==2&&rabbit.gethasCross()&&carrot.gethasCross()) {
return true;
}
return false;
}
/*
* 判断游戏是否胜利
* 前置条件:游戏结束
* 输入:无
* 运算:狼、羊、白菜均未被吃且全部渡过河,游戏胜利,否则失败
* 输出:游戏胜利--返回true ,失败--返回false
*/
public boolean hasWin(int choice) {
if(sheep.getisAlive()==false||cabbage.getisAlive()==false||rabbit.getisAlive()==false||carrot.getisAlive()==false) {
return false;
}
if(wolf.gethasCross()&&sheep.gethasCross()&&cabbage.gethasCross()) {
return true;
}else
if(choice==2&&rabbit.gethasCross()&&carrot.gethasCross()){
return true;
}else
return false;
}
}
package 农夫过河;
public class GameGui {
public void menu(int choice)
{
/* 显示菜单 */
System.out.println("==================Please choose operation============");
System.out.println("\t==========1:Cross the river alone===========");
System.out.println("\t==========2:Cross the river with wolf=========");
System.out.println("\t==========3:Cross the river with sheep============");
System.out.println("\t==========4:Cross the river with cabbage==========");
if(choice==2) {
System.out.println("\t==========5:Cross the river with rabbit============");
System.out.println("\t==========6:Cross the river with carrot==========");
System.out.println("\t==========7:Cross the river with wolf and rabbit===========");
System.out.println("\t==========8:Cross the river with wolf and sheep=========");
System.out.println("\t==========9:Cross the river with wolf and cabbage============");
System.out.println("\t==========10:Cross the river with wolf and carrot==========");
System.out.println("\t==========11:Cross the river with sheep and rabbit===========");
System.out.println("\t==========12:Cross the river with sheep and cabbage=========");
System.out.println("\t==========13:Cross the river with sheep and carrot============");
System.out.println("\t==========14:Cross the river with rabbit and cabbage==========");
System.out.println("\t==========15:Cross the river with rabbit and carrot============");
System.out.println("\t==========16:Cross the river with carrot and cabbage==========");
}
System.out.println("\t==========0:Quit===============");
System.out.println("===================================================");
System.out.println("Input the number:");
}
public void showStatus(Farmer farmer, Wolf wolf, Sheep sheep, Cabbage cabbage,Rabbit rabbit,Carrot carrot,int choice) {
/* 输出农夫、各种动物、物品的状态(生存、位置) */
farmer.showStatus();
wolf.showStatus();
sheep.showStatus();
cabbage.showStatus();
if(choice==2) {
rabbit.showStatus();
carrot.showStatus();
}
}
}
package 农夫过河;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Game game = new Game();
game.play();
}
}
package 农夫过河;
public class object {
boolean crossRiver=false;
boolean hasCross=false;
boolean isAlive=true;
public void showStatus() {
System.out.println();
}
public void eat() {
return ;
}
public void setcrossRiver(boolean a) {
crossRiver=a;
}
public void sethasCross(boolean a) {
hasCross=a;
}
public void setisAlive(boolean a) {
isAlive=a;
}
public boolean getcrossRiver() {
return crossRiver;
}
public boolean gethasCross() {
return hasCross;
}
public boolean getisAlive() {
return isAlive;
}
}
package 农夫过河;
public class Rabbit extends object {
public void showStatus() {
System.out.println("Rabbit is alive :"+isAlive+" Rabbit has Cross :"+hasCross);
}
public void eatCabbageandCarrot(Cabbage cabbage,Farmer farmer,Carrot carrot,int choice) {
if((cabbage.gethasCross()==this.hasCross)&&(farmer.gethasCross()!=this.hasCross)&&cabbage.getisAlive()==true)
cabbage.setisAlive(!(cabbage.getisAlive()));
if((carrot.gethasCross()==this.hasCross)&&(farmer.gethasCross()!=this.hasCross)&&carrot.getisAlive()==true&&choice==2)
carrot.setisAlive(!(carrot.getisAlive()));
}
}
package 农夫过河;
public class Sheep extends object{
public void showStatus() {
System.out.println("Sheep is alive :"+isAlive+" Sheep has Cross :"+hasCross);
}
public void eatCabbageandCarrot(Cabbage cabbage,Farmer farmer,Carrot carrot,int choice) {
if((cabbage.gethasCross()==this.hasCross)&&(farmer.gethasCross()!=this.hasCross)&&cabbage.getisAlive()==true)
cabbage.setisAlive(!(cabbage.getisAlive()));
if((carrot.gethasCross()==this.hasCross)&&(farmer.gethasCross()!=this.hasCross)&&carrot.getisAlive()==true&&choice==2)
carrot.setisAlive(!(carrot.getisAlive()));
}
}
package 农夫过河;
public class Wolf extends object{
public void showStatus() {
System.out.println("Wolf is alive :"+isAlive+" Wolf has Cross :"+hasCross);
}
public void eatSheepandRabbit(Sheep sheep,Farmer farmer,Rabbit rabbit,int choice) {
if((sheep.gethasCross()==this.hasCross)&&(farmer.gethasCross()!=this.hasCross))
sheep.setisAlive(!sheep.getisAlive()) ;
if((rabbit.gethasCross()==this.hasCross)&&(farmer.gethasCross()!=this.hasCross)&&choice==2)
rabbit.setisAlive(!rabbit.getisAlive()) ;
}
}