继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

重写“答答租车系统”

立马精神了
关注TA
已关注
手记 1
粉丝 5
获赞 0

新人小白,初识Java,独立完成了第二季最后的作业,其中的一些经验想与大家分享,望后至之士,酌情采纳。
刚开始我看到那个项目作业的时候,脑袋里也是一片空白,Java入门第二季面向对象的知识学的也是糊里糊涂,我觉得初学编程最难的地方就是从学习到自己动手写的过程,也就是编程思想的形成,而我恰好处于这个地方。我不想再次放弃,想想自己对面向对象还是很模糊,就从封装那里重新看,看完了自己动手写,写的是老师在抽象类那章留下的例题:计算长方形和圆形的面积、周长。开始只用了封装的get/set方法,运行成功后,又重新看了继承那章的内容,并加入了继承的方法改写了原来的程序,也运行成功了,然后又看了多态。这一过程花了两三天的时间,我对面向对象的思想的理解比原来更深刻了。然后我又花了一天的时间,写出了答答租车系统,完成了作业。每一次的编程都是一次自我思考的过程,同时在编程的过程中也在积累着经验,至此我才体会到前辈们说的学习编程勤打代码是最重要的!


今天是国庆节,重新写了答答租车系统。在看了慕课网的java入门视频后,脑子里还是很混乱的,对于面向对象的内容还不是十分理解,到了第三季的异常和集合框架,看的更是一脸懵逼,但是我真的很想学好java,所以我又去网上找了别的入门是重新开始看。我看的是毕向东老师的25天入门视频,内容深入浅出,也十分的幽默,看起来也不会太累。在看完了十天的内容后,也就是讲完了面向对象的封装、继承和多态,我觉得再将这个答答租车系统写一遍。
刚开始我仅仅想到租车的序号、汽车名称、租金抽象成一个父类,建立载人车、载货车和皮卡雪三个子类,因为容量有载人和载货之分,载人车不具备载货功能,载货车又不具备载人功能,所以我并没有把容量这个属性放到父类中去。这里,我是参考了慕友的思路,将载人和载货这两个功能抽象成两个接口,由载人车实现载人接口,传入容量属性;由载货车实现载货接口,传入容量属性;而皮卡雪需要同时实现这两个接口。感觉真的是十分巧妙而有趣。
在写代码的过程中,我从慕友的代码中学习的了:通过创建父类类型对象数组来批量的进行对象初始化,当然这个方法我并没有在其他地方见过,以后还会在实践中来探索它的使用方法。同时我也学到了toString()方法的使用:当打印一个对象时,如果该对象所属的类中包含了toString()方法,那么就会自动调用toString()方法打印其中的内容,toString()方法时Object类中给定的方法,使用时通常都要进行改写。我也遇到了一个问题:就是当要利用多态进行向下转型来使用子类独有的方法时,不能讲父类类型对象数组向下转型为子类类型对象数组,会报错,而只能将对象一个一个转型,不知是否是这样的?在这次的重写的代码中,我也新增实现了输出所租汽车名称的去重,也就是如果同一辆车被重复选择,再输的账单上,该汽车名称只会出现一次,具体实现方法可以看我代码中的注释。
下面是我的答答租车系统的代码

//父类  Car
public class Car {
    private int id;
    private String name;
    private int price;
    public Car() {}
    public void setId(int id)
    {
        this.id=id;
    }
    public int getId()
    {
        return this.id;
    }

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

    public void setPrice(int price)
    {
        this.price=price;
    }
    public int getPrice()
    {
        return this.price;
    }

    public String toString()
    {
        return this.id+"\t"+this.name+"\t"+this.price+"\t";
    }
}
//接口类 载人功能
public interface People {
    public void setPeople(int people);
    public int getPeople();
}
//接口类  载货功能
public interface Goods {
    public void setGoods(int goods);
    public int getGoods();
}
//子类  载人车
public class PeopleCar extends Car implements People {
    private int people;
    public PeopleCar(int id,String name,int price,int people)
    {
        super.setId(id);
        super.setName(name);
        super.setPrice(price);
        this.setPeople(people);
    }

    @Override
    public void setPeople(int people)
    {
        this.people=people;
    }
    public int getPeople() {
        // TODO Auto-generated method stub
        return people;
    }
    public String toString()
    {
        return super.getId()+"\t"+super.getName()+"\t"+super.getPrice()+"元/天"+"\t"+"载人:"+getPeople();
    }
}
//子类  载货车
public class GoodsCar extends Car implements Goods {
    private int goods;
    public GoodsCar(int id,String name,int price,int goods)
    {
        super.setId(id);
        super.setName(name);
        super.setPrice(price);
        this.setGoods(goods);
    }
    public void setGoods(int goods)
    {
        this.goods=goods;
    }
    @Override
    public int getGoods() {
        // TODO Auto-generated method stub
        return goods;
    }
    public String toString()
    {
        return super.getId()+"\t"+super.getName()+"\t"+super.getPrice()+"元/天"+"\t"+"载货:"+this.getGoods();
    }
}
//子类  皮卡雪
public class PickCar extends Car implements Goods, People {
    private int people;
    private int goods;
    public PickCar(int id,String name,int price,int people,int goods)
    {
        super.setId(id);
        super.setName(name);
        super.setPrice(price);
        this.setPeople(people);
        this.setGoods(goods);
    }
    public void setPeople(int people)
    {
        this.people=people;
    }
    @Override
    public int getPeople() {
        // TODO Auto-generated method stub
        return people;
    }
    public void setGoods(int goods)
    {
        this.goods=goods;
    }

    @Override
    public int getGoods() {
        // TODO Auto-generated method stub
        return goods;
    }
    public String toString()
    {
        return super.getId()+"\t"+super.getName()+"\t"+super.getPrice()+"元/天"+"\t"
                +"载人:"+this.getPeople()+"载货:"+this.getGoods();
    }
}
//实现类
import java.util.Scanner;;
public class MainTest {

    private static Scanner input=new Scanner(System.in);

    private static Car[] car= {new PeopleCar(1, "奥迪A4", 500,4),//多态,父类引用指向子类对象
            new PeopleCar(2, "马自达6", 400, 4),//在创建对象的时候直接对对象进行初始化
            new PickCar(3, "皮卡雪6", 450, 4, 2),//因为在子类中定义了含参的构造方法
            new PeopleCar(4, "金龙", 800, 20),
            new GoodsCar(5, "松花江", 400, 4),
            new GoodsCar(6, "依维河", 1000, 20)};

    private static void print(String str)//自定义的输出字符串的方法
    {
        System.out.println(str);
    }

    private static int carNums()//输入你要租车的数量
    {
        print("请输入您要租车的数量:");
        return inPut(2);
    }

    private static int[] carSelect(int num)//接收输入的租车数量,循环打印提示要租车的序号,
    {                                   //并把序号存入一个数组中
        int[] ids=new int[num];
        for(int i=1;i<=num;i++)
        {
            print("******请输入第"+i+"辆车的序号******");
            int in=input.nextInt();
            while(in<1||in>6)//输入选择车辆的序号超出给定范围不予通过
            {
                print();
                print("******请输入第"+i+"辆车的序号******");
                in=input.nextInt();
            }
            ids[i-1]=in;//将输入的要租车的序号存储到数组ids中
        }
        return ids;
    }

    private static void print()//重写自定义函数print
    {
        print("******请输入合法的数据******");
    }

    private static int inPut(int i)//判断输入的值是否异常
    {
        int in=input.nextInt();
        if(i==1)
        {
            while(in!=0&&in!=1)
            {
                print();
                print("您是否要租车:1:是   0:否");
                in=input.nextInt();
            }
        }else if(i==2)
        {
            while(in<1)
            {
                print();
                print("请输入您要租车的数量:");
                in=input.nextInt();
            }
        }else if(i==3)
        {
            while(in<1)
            {
                print();
                print("******请输入租车天数******");
                in=input.nextInt();
            }
        }
        return in;
    }

    private static int days()
    {
        print("******请输入租车天数******");
        return inPut(3);
    }
//下面是我设计的输出汽车名称去重算法,感觉有点麻烦  
/*既然载人车和载货车要分别计算和输出,不如将得到的选择的车辆数组ids分成载人和载货两个数组
定义两个函数peopleIds和goodsIds,传入ids数组参数,返回只载人和只载货的数组
*/
    private static int[] peopleIds(int[] ids)
    {
        int[] peopleIds= new int[ids.length];
        for(int i=0;i<ids.length;i++)
        {
            if(ids[i]!=5&&ids[i]!=6)
                peopleIds[i]=ids[i];
            else
                continue;
        }
        return peopleIds;
    }

    private static int[] goodsIds(int[] ids)
    {
        int[] goodsIds=new int[ids.length];
        for(int i=0;i<ids.length;i++)
        {
            if(ids[i]==3||ids[i]==5||ids[i]==6)
                goodsIds[i]=ids[i];
            else
                continue;
        }
        return goodsIds;
    }

/*然后定义两个去重函数,接收分别接收载人车和载货车的序号数组,先进行选择比较:取第一个元素,和其他元素比较,
 * 如果两个元素“==”了,就将该元素置为0,依次循环
 * 然后要通过get方法取得车辆的名字,其中要判断一下如果数组的元素值为0,就continue,最后打印一下
 * */   
    private static String[] peopleCarNames(int[] arr)
    {
        int[] peopleIds=arr;
        for(int i=0;i<peopleIds.length-1;i++)
        {
            for(int j=i+1;j<peopleIds.length;j++)
            {
                if(peopleIds[i]==peopleIds[j])
                    peopleIds[i]=0;
                else
                    continue;
            }
        }
        String[] peopleCarNames=new String[arr.length];
        for(int k=0;k<peopleCarNames.length;k++)
        {
            if(peopleIds[k]==0)
                continue;
            else
                peopleCarNames[k]=car[peopleIds[k]-1].getName();
        }
        return peopleCarNames;
    }

    private static String[] goodsCarNames(int[] arr)
    {
        int[] goodsIds=arr;
        for(int i=0;i<goodsIds.length-1;i++)
        {
            for(int j=i+1;j<goodsIds.length;j++)
            {
                if(goodsIds[i]==goodsIds[j])
                    goodsIds[i]=0;
                else
                    continue;
            }
        }
        String[] goodsCarNames=new String[arr.length];
        for(int k=0;k<goodsCarNames.length;k++)
        {
            if(goodsIds[k]==0)
                continue;
            else
                goodsCarNames[k]=car[goodsIds[k]-1].getName();
        }
        return goodsCarNames;
    }

//因为不给已经创建好固定长度的字符串所有元素赋值,所以出现了null,所以要手动打印数组,并且去除null
    private static void printArrays(String[] arr)
    {
        for(int i=0;i<arr.length;i++)
        {
            if(arr[i]==(null))
                continue;
            else
                System.out.print(arr[i]+"\t");
        }
    }

/*因为需要调用子类独有的获取载人数或载货数的方法,所以需要利用多态进行向下转型,但是需要注意的是因为之前创建的类型为Car的数组中
 * 包含了三个子类的对象,所以如果直接强制向下转型为某一个子类对象数组,将出现子类A属于子类B的错误,所以需要处理一下,
 * 我的做法是,将每个子类中每一个对象分别向下进行转型,再调用子类的方法。(我之前尝试将Car类型数组划分为三个与之对应的子类型数组,
 * 再将此数组进行向下转型,依然报错,难度是对象所属之间也有冲突?不太明白,求高人解答)
 * */
//需要计算载货车和载人车的荷载数,计算值可以直接打印输出,只需要传入之前分离好的载人车或载货车序号数组,
//通过get方法获取数值,再进行计算就可以了,需要注意的是,传入的数组参数中可能会存在值为0的元素,需要判断一下

    private static void peopleSum(int[] arr) {
        PeopleCar people1=(PeopleCar)car[0];
        PeopleCar people2=(PeopleCar)car[1];
        PeopleCar people4=(PeopleCar)car[3];
        PickCar pick=(PickCar)car[2];
        int sum=0;
        for(int i=0;i<arr.length;i++)
        {
            switch(arr[i]) {
            case 0: break;
            case 1: sum=sum+people1.getPeople();
                break;
            case 2: sum=sum+people2.getPeople();
                break;
            case 3: sum=sum+pick.getPeople();
                break;
            case 4: sum=sum+people4.getPeople();
            }
        }
        print("共载人:"+sum+"人");
    }

    private static void goodsSum(int[] arr)
    {
        PickCar pick=(PickCar)car[2];
        GoodsCar goods5=(GoodsCar)car[4];
        GoodsCar goods6=(GoodsCar)car[5];
        int sum=0;
        for(int i=0;i<arr.length;i++)
        {
            switch(arr[i]) {
            case 0:break;
            case 3:sum=sum+pick.getGoods();
                break;
            case 5:sum=sum+goods5.getGoods();
                break;
            case 6:sum=sum+goods6.getGoods();
            }
        }
        print("共载货:"+sum+"吨");
    }

/*最后计算租车的总价格,这里直接传入ids数组,调用get方法取得价格数值进行计算即可
 * */
    private static void sumAll(int[] ids,int days)
    {
        int sum=0;
        for(int i=0;i<ids.length;i++)
            sum=sum+car[ids[i]-1].getPrice();
        print("******租车的总价格为:"+sum*days+"元");

    }
//***********************************************************************   
    public static void main(String[] args)
    {

        print("--------------欢迎使用答答租车系统--------------");
        print("您是否要租车:1:是   0:否");
        int in=inPut(1);
        if(in==1)
        {
            print("序号"+"\t"+"汽车名称"+"\t"+"租金"+"\t"+"容量");
            for(int i=0;i<car.length;i++)
                System.out.println(car[i]);//直接打印对象会自动调用Object类中的toString()方法
            int num=carNums(); 
            int[] ids=carSelect(num);
            int days=days();//接收租车的天数
            print("您的账单:");
            print("******可载人的车有:");
            printArrays(peopleCarNames(peopleIds(ids)));/*先调用分类载人车和载货车数组函数,返回载人车序号数组;
            再调用将序号转换为车名函数,返回车名数组,最后调用剔除null值打印车名函数*/
            peopleSum(peopleIds(ids));
            print("******可载货的车有:");
            printArrays(goodsCarNames(goodsIds(ids)));
            goodsSum(goodsIds(ids));
            sumAll(ids,days);           
        }else 
        {
            print("-------------------感谢您的使用!再见!-------------------");
        }
    }
}
打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP