两道构造方法加数组练习题带来的进阶

综合练习题让你编程能力真正进阶。


文章适合于初学或即将开始学习JAVA的小伙伴,你将看到鲜活的真实错误案例,还有复盘的注意事项。

练习题背景

构造方法、静态关键字、封装,还有数组都算是JAVA编程的核心基础。
这两个练习题对我最大的挑战表面上是“构造方法”、“数组”的技法应用,实际是面向对象程序思路框架的搭建。第一题数组是对象的属性,第二题对象是数组的元素,不得不说都是跨了很多知识点的经典题目。

题目一:使用一维数组,模拟栈数据结构

1、这个栈可以存储java中的任何引用类型的数据;
2、在栈中模拟push方法压栈;(含“栈满了”的提示信息);
3、在栈中模拟pop方法弹栈;(含“栈空了”的提示信息)

题一主要围绕一个包含数组属性的类,并在类文件中编写响应的push方法、pop方法。

修改前代码
以下是main程序代码:
public class stacktest {
    public static void main(String[] args) {
        //创建对象
         MyStack mystk = new MyStack(new Object[]{1,2,3,5},5);
         //main函数只放声明,初始化统一体现在main程序中
        //通过push方法增加数据,包含栈底即将满时报错
        mystk.push(1); 
      //通过pop方法推出数据,包含栈底即将为空时报错
         mystk.pop();
         }
}

以下是核心类文件代码:
class MyStack {
    private Object[] elements;
    private int ix;   //栈帧;
    //无参构造函数 =========================
    public MyStack(){
        elements = new Object[5];
         ix = -1;    }
    //创建push方法;
    public void push(Object obj){
        if (ix < elements.length-1){
            elements[ix] = obj;
            System.out.println("成功把新元素"+ obj +"压入到下标为"+ ix + "的位置");
            ix++;//错误标记_这样会导致栈刚堆到满时下标会超出,应该使移完下标再赋值}else {
            System.out.println("栈满了");        }
    }
    //创建pop方法;
    public void pop(){
        if (ix>=0){
            Object objtemp = elements[ix];
            elements[ix]=null;
            System.out.println("成功把位置下标为"+ ix + "的栈顶元素"+objtemp+ "弹出");//这里的对象不需要toString?
            ix--;        }else {
            System.out.println("栈空了");        }
    }
}
修改后代码:
以下是main程序代码:
public class stacktest {
    public static void main(String[] args) {
        //创建对象
       MyStack mystk = new MyStack();
       //main函数只放声明,初始化统一体现在main程序中
       //通过push方法增加数据,包含栈底即将满时报错
        mystk.push(1); 
      //通过pop方法推出数据,包含栈底即将为空时报错
         mystk.pop();
         }
}
以下是核心类文件代码:
class MyStack {
    private Object[] elements;
    private int ix;  //栈帧;
    //无参构造函数 =========================
    public MyStack(){
        elements = new Object[5];
         ix = -1;    }
   //创建push方法;
    public void push(Object obj){
        if (ix < elements.length-1){
            ix++; 
            elements[ix] = obj;
            System.out.println("成功把新元素"+ obj +"压入到下标为"+ ix + "的位置");
         }else {
            System.out.println("栈满了");        }
    }
    //创建pop方法;
    public void pop(){
        if (ix>=0){
            Object objtemp = elements[ix];
            elements[ix]=null;
            System.out.println("成功把位置下标为"+ ix + "的栈顶元素"+objtemp+ "弹出");//这里的对象不需要toString?
            ix--;        }else {
            System.out.println("栈空了");        }
    }
}

题目二:用到二维数组编写酒店管理系统相关程序,模拟订房、退房、打印所有房间状态等功能

1、每一个房间Room应该有:房间编号、房间类型、房间是否空闲;
2、输入房间编号可以预定房间;
3、输入房间编号可以退房;
4、输入某个执行可以查看所有房间状态

题二相对难一些,涉及到二维数组,而且是对象数组。具体代码分成了“房间类”、“酒店类”、“main程序”。
单独拆解出“酒店类”,而且还和“房间类”存在复杂的嵌套关系,主要是由于“房间对象初始化时”、“查看全部房间状态时”都有一块二维数组遍历的代码块,放main程序太长了。

修改前代码
以下是main程序代码:
public class hoteltest {
    public static void main(String[] args) {
        //初始化一个酒店
        Hotel ht = new Hotel();
         Scanner scan = new Scanner(System.in);
        System.out.println("请输房间号,如'0113即一楼第13间':");   
       //s.nextLine();//错误标记,scan仍然是一个引用
        //预定某个房间
        ht.book(s);
        //退订某个房间
        ht.unbook(s);
        //查看所有房间状态
        allbookstatus(ht);//错误标记_执行方法时,只有引用.方法名(),没有方法名(引用)
    }
}
以下是酒店类代码:
public class Hotel {
    //“拥有房间的声明”
    Room[][] myrm;
    //无参构造方法:
    public Hotel(){
        myrm = new Room[3][15];
 //这一步只是给数组元素进行初始化分配空间,还需要给每个元素初始化分配空间; 不仅适用于对象数组,也适用于其他引用数据类型的数组;
        for (int i=0; i<3; i++){
            for (int j=0; j<15; j++){
                Room room = new Room(i, j); //错误标记_此处应该要到引用,上方已声明,不能新建引用:Room room; }
        }
    }
    //预订房间
    public void book(String s){
        int floor = Integer.parseInt(s.substring(0,2)) - 1;
        int num = Integer.parseInt(s.substring(2,4)) - 1;
        myrm[floor][num].book();
    //嵌套类的方法重名没关系,对象所归属的类不同;}
    //退订房间
    public void unbook(String s){
        int floor = Integer.parseInt(s.substring(0,1)) - 1;
    //错误标记_endindex应该取2不是1
        int num = Integer.parseInt(s.substring(2,4)) - 1;
        myrm[floor][num].unbook();    }
    //查看所有房间状况
    public void allbookstatus(){ //错误标记_方法名(a)、要加void        for (int i=0; i<myrm.length; i++){
            for (int j=0; j<myrm[0].length; j++){
                switch (myrm[i][j].getRoomstatus()){//封装              
                   case 0:
                        System.out.print("房间号"+myrm[i][j].roomnumber+"的状态:"+"空闲,"); 
                       break;
                    case 1:
                        System.out.print("房间号"+myrm[i][j].roomnumber+"的状态:"+"预定中,"); 
                       break;
                    case 2:
                        System.out.print("房间号"+myrm[i][j].roomnumber+"的状态:"+"使用中,"); 
                       break;                }
            }
            System.out.println("");        }
    }
}
以下是房间类代码:
public class Room{
    String roomnumber;
    int roomtype;
    private int roomstatus; //封装私有化
    public int getRoomstatus() {
        return roomstatus;    }
    public void setRoomstatus(int roomstatus) {
        this.roomstatus = roomstatus;    }
    public void Room(){//错误标记_此处不能有void,有对应普通方法,使得缺少无参构造函数初始化为空值
        roomtype = (int)(Math.random()*3);//0标间,1大床房,2豪华间,3商务间
        roomstatus = (int)(Math.random()*2);//0空间,1预定中,2使用中    }
    public Room(int floor, int num){
        this.roomnumber = String.format("%02d%02d", floor, num);
        roomtype = (int)(Math.random()*3);//0标间,1大床房,2豪华间,3商务间
        roomstatus = (int)(Math.random()*2);//0空间,1预定中,2使用中    }
    public void book(){
        if (roomstatus==1){
            System.out.println("预定不成功,该房间已经处于预定中状态。");        }else if (this.roomstatus==2){
            System.out.println("预定不成功,该房间已经处于使用中状态。");        }else {
            roomstatus = 1;
            System.out.println("预定成功");}
 }
    //退订房间
    public void unbook(){
        roomtype = 0;
        System.out.println("退订成功");    }
}
修改后代码
以下是main程序代码:
public class hoteltest {
    public static void main(String[] args) {
        //初始化一个酒店
       Hotel ht = new Hotel();
       Scanner scan = new Scanner(System.in);
       System.out.println("请输房间号,如'0113即一楼第13间':");  
     String s = scan.nextLine();
       //预定某个房间
       ht.book(s);
       //退订某个房间
       ht.unbook(s);
       //查看所有房间状态
       ht.allbookstatus();//错误标记
   }
}
以下是酒店类代码:
public class Hotel {
    //“拥有房间的声明”
   Room[][] myrm;
   //无参构造方法:
   public Hotel(){
        myrm = new Room[3][15];
//这一步只是给数组元素进行初始化分配空间,还需要给每个元素初始化分配空间;不仅适用于对象数组,也适用于其他引用数据类型的数组;
       for (int i=0; i<3; i++){
            for (int j=0; j<15; j++){
                myrm[i][j] = new Room(i, j); //错误标记_此处应该要到引用,上方已声明,不能新建引用:Room room; }
        }
    }
    //预订房间
   public void book(String s){
        int floor = Integer.parseInt(s.substring(0,2)) - 1;
        int num = Integer.parseInt(s.substring(2,4)) - 1;
        myrm[floor][num].book();
    //嵌套类的方法重名没关系,对象所归属的类不同;}
    //退订房间
   public void unbook(String s){
        int floor = Integer.parseInt(s.substring(0,2)) - 1;
    //错误标记_endindex应该取2不是1
       int num = Integer.parseInt(s.substring(2,4)) - 1;
       myrm[floor][num].unbook();    }
    //查看所有房间状态
   public void allbookstatus(){ //错误标记_方法名(a)、要加void        for (int i=0; i<myrm.length; i++){
            for (int j=0; j<myrm[0].length; j++){
                switch (myrm[i][j].getRoomstatus()){//封装              
                   case 0:
                        System.out.print("房间号"+myrm[i][j].roomnumber+"的状态:"+"空闲,");
                       break;
                    case 1:
                        System.out.print("房间号"+myrm[i][j].roomnumber+"的状态:"+"预定中,");
                       break;
                    case 2:
                        System.out.print("房间号"+myrm[i][j].roomnumber+"的状态:"+"使用中,");
                       break;                }
            }
            System.out.println("");        }
    }
}
以下是房间类代码:
public class Room{
    String roomnumber;
    int roomtype;
    private int roomstatus; //封装私有化
   public int getRoomstatus() {
        return roomstatus;    }
    public void setRoomstatus(int roomstatus) {
        this.roomstatus = roomstatus;    }
    public Room(){//错误标记_此处不能有void,有对应普通方法,使得缺少无参构造函数初始化为空值
       roomtype = (int)(Math.random()*3);//0标间,1大床房,2豪华间,3商务间
       roomstatus = (int)(Math.random()*2);//0空间,1预定中,2使用中    }
    public Room(int floor, int num){
        this.roomnumber = String.format("%02d%02d", floor, num);
       roomtype = (int)(Math.random()*3);//0标间,1大床房,2豪华间,3商务间
       roomstatus = (int)(Math.random()*2);//0空间,1预定中,2使用中    }
    public void book(){
        if (roomstatus==1){
            System.out.println("预定不成功,该房间已经处于预定中状态。");        }else if (this.roomstatus==2){
            System.out.println("预定不成功,该房间已经处于使用中状态。");        }else {
            roomstatus = 1;
           System.out.println("预定成功");}
 }
    //退订房间
   public void unbook(){
        roomtype = 0;
       System.out.println("退订成功");  

总结

通过视频自学经常为了追求进度而实际没有深入思考底层逻辑,遇到真正的综合题就原形毕露,感觉真是“寸码难敲”。好在做习题相当于带着问题去复习,事半功倍,尤其是错过的地方印象更深刻了。

这次让我重查并且印象深刻的关键知识点有:

主题知识点
构造方法不需要指定返回值类型、不能写void(写上就成为普通方法)
构造方法构造方法的方法名必须和类名保持一致
构造方法构造方法的作用:创建对象、给对象的各个属性赋初始值
构造方法返回值、返回值类型都不需要写(实际有返回值,自动返回)
构造方法当一个类没有定义构造方法,系统默认给该类提供一个无参数的构造方法,缺省构造器
构造方法多个实参列表组合的构造方法已经构成“重载”
Static关键字修饰“静态变量”、“静态方法”,都是类级别的特征,和具体对象无关
Static关键字用类名.方法名,不用对象(static在初始化时就已经分配内存,所以不需要new来分配内存):
通俗点就是“无对象要加static,有对象不加static”
封装作用是“提高对象属性的安全性”,用private关键字来体现
封装要结合setter()、getter()方法

最后,谢谢大家查看,我们在打造自学JAVA小部落,希望有同样目标的小伙伴和大佬加入。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值