• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Objective-C 【完整OC项目-购票系统-系统分析-代码实现】

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
电影院买票系统/演唱会买票系统

需求分析:

首先我们进入系统,然后会选择买电影票还是买演唱会票,所以这牵扯两个系统的合成。但是我们知道都是买票系统,所以我们可以先创建一个类,属于购买电影票和演唱会的票的共同点,我们可以创建一个Ticket,让电影票MovieTicket和演唱会票ConcertTicket都去继承Ticket,然后再在MovieTicket和Concert中写他们各自特有的方法。所以这就牵扯到了三个类。再去想,我们在main函数中调用买电影票buyMovieTicket的方法和买演唱会票buyConcertTicket的方法,严格的讲,我们应该把他们定义成函数,因为我们在这里不知道用什么类/实例对象去调用这两个买票的方法,所以我们不如将他们定义成无参方法,然后让用户去选择到底是调用buyMovieTicket还是调用buyConcertTicket方法。

那么下一步,我们就应该进入这两个买票的函数了。

(1)思路分析

首先我们先进入buyMovieTicket函数。在这个函数里我们要调用许许多多的方法,包括买票、显示正在上映的电影、选择电影、选择排数、选择座位号、支付、出票。那么想要调用这些方法,我们必然要创建实例对象进行调用,那么我们应该用哪个类去创建对象呢?首先不能用Ticket,因为这个Ticket是一个假象类,并不是实际存在的,那么用MovieTicket类呢?显然用MovieTicket类实例化一个对象我们应该称之为是“一张电影票”,然后在这这个电影票的实例对象上有很多实例变量信息。显然电影票是不能调用买票这个方法的(因为我们在得到票之前就要调用买票的方法了)。那么我们显然要再创建一个类,既然我们平时都去电影院去看电影,那么我们何不创建一个Cinema类,寓意到了电影院看到电影院提供的信息,然后进行买票。这样就合理了许多。那么Cinema类应该具备哪些实例变量还有方法呢?显然一个电影院应该有一个名字,我们可以设置为_cinemaName,另外进入电影院我们可以看到展示在大屏幕上滚动的电影放映信息,比如说今天要放5部电影,我们可以建立一个数组,然后去存放这五部电影,然后供用户选择。那么这五部放映的电影应该具备怎样的属性(实例变量)呢?显然,电影信息和电影票信息相仿,我们可以实例化一个MoiveTicket的实例数组ticket[5]去存储这五部电影信息,然后这个数组中的每一个数组成员都是一部可能要被用户观看的电影信息,而数组成员因为是MovieTicket类型的,所以可以继承MovieTicket中的一些属性,这样我们在初始化Cinema实例对象的时候就可以重写构造方法,在创建实例对象的同时完成对五部上映影片的信息数组创建,然后在buyMovieTicket函数中调用第一个对象方法buyTicket,当然buyTicket这个行为是在电影院中产生的,所以buyTicket方法属于Cinema类。

我们完成了非常重要的一步,也就是重写构造方法,然后进入buyTicket这个对象方法,然后去调用,进而我们需要完成:显示正在上映的电影(-(void)list;),选择电影(-(void)selectMovie;),选择排数(-(void)selectRow;),选择座位号(-(void)selectCol;),开始支付(-(void)pay;),出票(-(void)printTicket;)等一系列的方法操作。★而每一个方法结束时都会在方法内部调用第二个方法。直到最后购买完电影票为用户打印票的信息。★

具体的步骤就是这样,具体实现起来大致有这么两个难题:第一,我们应该清楚怎么在合适的位置定义这些属性(实例变量);第二,我们应该知道这些方法具体应该怎么实现。

好了到现在,buyMovieTicket 这个函数需要进行的操作乃至后面的一系列操作我们已经考虑到了,在思路分析这一个环节我们做这么多就够了,接下来就是写代码部分。

(2)代码部分

时间原因我们只写了购买电影票的流程,我们没有写演唱会票的购买流程。

整个代码我们分为了两个文件夹和一个main函数:(每个文件夹中独立出来了各个类的.h和.m文件)

①Cinema文件夹

——————————————————Cinema.h——————————————————


#import <Foundation/Foundation.h>
#import "MovieTicket.h"

@interface Cinema : NSObject
{
    //电影院的名字
    NSString * _cinemaName;

    //电影院正在上映的五部影片,都是MovieTicket类型,那么不妨我们将这些影片对象存在一个MovieTicket类型的数组中
    MovieTicket *tickets[5];
}

//当然我觉得我们有必要定义一个新的构造方法
-(instancetype)initWithCinemaName:(NSString *)cinemaName;

//开始购票
-(void)buyTickets;

//显示正在上映的电影
-(void)listMovies;

//选择电影
-(void)selectMovies;

//选择排数
-(void)selectRow;

//选择座位号
-(void)selectCol;

//开始支付
-(void)payTickets;

//出票(打印票的信息)
-(void)printTickets;


@end


——————————————————Cinema.h——————————————————

——————————————————Cinema.m——————————————————


#import "Cinema.h"

//定义一个全局变量来记录电影编号
int selectNo;

//宏定义电影院影厅的行数和列数
#define ROW 8
#define COL 15

@implementation Cinema

//重写构造方法
-(instancetype)initWithCinemaName:(NSString *)cinemaName
{
    if (self=[super init]) {
//        让_cinemaName等于我们传进来的cinemaName
        _cinemaName=cinemaName;
        
//        接下来我们要初始化Cinema中的第二个实例变量,也就是MovieTicket类型的数组
//        自然我们要用到for循环来进行初始化(这个地方注意,虽然是初始化数组中的所有元素,但是我们也是只能保证里面的个别信息不同,也就是能循环起来值的地方可以做到不同,而一些文字部分,暂时无法做到初始化不一样的值)
        for (int i=0; i<5; i++) {
//            for循环中每次都执行一次创建一个新的MovieTicket的实例对象(共创建5个),然后为其实例变量赋值
            MovieTicket *mvTicket=[MovieTicket new];
            //            电影名称
                        mvTicket.name=[NSString stringWithFormat:@"碟中谍 %02d",i+1];
            //            导演
                        mvTicket.director=@"王中尧";
            //            主演
                        mvTicket.actor=@"马星泽,张桐,郑二安";
            //            影厅信息
                        mvTicket.place=[NSString stringWithFormat:@"%02d 厅",i+1];
            //            首映时间
                        mvTicket.showTime=[NSString stringWithFormat:@"200%d-12-31",i];
            //            开始时间
                        mvTicket.startTime=[NSString stringWithFormat:@"1%d:15",i];
            //            电影编号
                        mvTicket.no=i+1;
            //            时长
                        mvTicket.lengthTime=120;
            //            票价
                        mvTicket.movieTicketPrice=35;
//            最后把我们初始化完毕的实例对象赋给MovieTicket类型的数组

            tickets[i]=mvTicket;

//下面有一个图来呈现一种错误的初始化对象数组的方式


//如果用上面图片的方式,我们看到输出的结果不是0就是null,所以说是错误的,为什么呢?那是因为系统不知道你往数组里初始化的什么类型的数据,只有你自己知道你初始化的数据类型是合适的,但是系统并不晓得,他是怀疑的,系统会认为你还会存一些错误的数据类型。这种隐藏的错误,是会报错的。

        }
        
    }
    return self;
}

//开始购票
-(void)buyTickets
{
    NSLog(@"开始购票!");
//    这里没有什么多余的实现过程,购票就直接进入下一个方法:显示正在上映的电影
    [self listMovies];
}

//显示正在上映的电影
/*
 思路:
 1)利用已有的tickets数组,打印数组信息
 2)遍历数组
 格式:
 
 编号  名称
 导演  主演
 开始时间  时长
 首映时间  影厅信息
 执行票价
 */
//显示正在上映的电影
-(void)listMovies
{
    for (int i=0; i<5 ; i++) {
        NSLog(@"\n\n编号:%d  名称:%@\n导演:%@  主演:%@\n开始时间:%@  时长:%d\n首映时间:%@  影厅信息:%@\n执行票价:%.2f\n\n",tickets[i].no,tickets[i].name,tickets[i].director,tickets[i].actor,tickets[i].startTime,tickets[i].lengthTime,tickets[i].showTime,tickets[i].place,tickets[i].movieTicketPrice);
    }
    
//    选择电影,进行下一方法
    [self selectMovies];
}

//选择电影
-(void)selectMovies
{
    NSLog(@"请选择你要购买的电影编号并输入:\n\n");
    
//    由用户输入编号,然后判断编号是否正确,如果正确,将值赋给创建好的全局变量selectNo
    int num;
    scanf("%d",&num);
    if (num>0||num<=5) {
        selectNo=num;
    }
    else
//        如果输入错误,直接跳出程序
        return;
    
    //如果输入成功,提示选择的电影
    NSLog(@"\n您选择了%d号电影,名称为%@\n\n",selectNo,tickets[selectNo-1].name);
    
//    选择排数,进行下一方法
    [self selectRow];
}

//选择排数
/*
 
 思路:
 1)把电影院的座位信息都打出来看一下
 2)提示,当前影厅有多少排,每排有多少个座位
 3)提示让用户选择排数
 4) 保存排数信息
 */

//选择排数
-(void)selectRow
{
    NSLog(@"\n选择排数");
    NSLog(@"\n下面是该场次的座位信息:\n\n");
    
//    先打印电影院位置信息让用户看一下
    for (int i=-1; i<ROW; i++) {
        for (int j=-1; j<COL; j++) {
            if (i==-1) {
                printf("%02d ",j+1);
            }
            else if(j==-1)
            {
                printf("%02d",i+1);
            }
            else
                printf("  +");
        }
        printf("\n");
    }
    
    //    提示该厅有多少排,每排有几个座位
    printf("\n该厅有%d排,每排有%d个座位\n\n",ROW,COL);
    printf("请选择排数:\n\n");
    //    让顾客选择排数,输入排数的时候,最好将顾客输入的值判断一下
    int num;
    scanf("%d",&num);
    //    判断条件:排数必须是1~8之间的数字
    if (num>0||num<=8) {
 
//      将合理的排数赋给rowNum
//      这里解释一下selectNo-1,首先上一步骤已经确定了影片的编号,然后影片的实际编号是0~4,所以要在输入编号的基础上减一才能用
        tickets[selectNo-1].rowNum=num;
    
    }
//      选择座位,进入下一方法
    [self selectCol];
}

//选择座位号
-(void)selectCol
{
    NSLog(@"\n选择座位号");
    int num;
    scanf("%d",&num);
    if (num>0||num<=15) {
        
//      将合理的排数赋给rowNum
        tickets[selectNo-1].colNum=num;
    }
    
    //将用户选择的票信息打印出来让用户查看,然后让用户确认
    //格式:
    //您选择 xxx 影片
    //开始时间:          电影时长:
    //第 xx 排           第 xx 座
    //价格:

    NSLog(@"\n\n 您选择的是影片:      %@ \n 开始时间: %@     电影时长: %d\n 第 %d 排   第 %d 座位\n 您所支付的票价为: %.2f\n\n",tickets[selectNo-1].name,tickets[selectNo-1].startTime,tickets[selectNo-1].lengthTime,tickets[selectNo-1].rowNum,tickets[selectNo-1].colNum,tickets[selectNo-1].movieTicketPrice);
    
    NSLog(@"\n请确认您的购票信息:(1.确认   0.取消)\n");
    int flag;
    scanf("%d",&flag);
    if (flag) {
        //    支付,进入下一方法
        [self payTickets];
    }
    else
        NSLog(@"退出系统!");
}

//开始支付
-(void)payTickets
{
    NSLog(@"\n开始支付...........");
    NSLog(@"\n请等待!");
    NSLog(@"\n支付成功!!!");
    [self printTickets];
}

//出票(打印票的信息)
-(void)printTickets
{
    NSLog(@"\n出票");
    
    NSLog(@"\n 您选择的是影片: %@ \n 开始时间: %@ 电影时长: %d\n 第 %d 排   第 %d 座位\n 您所支付的票价为: %.2f\n 影厅:%@\n\n",tickets[selectNo-1].name,tickets[selectNo-1].startTime,tickets[selectNo-1].lengthTime,tickets[selectNo-1].rowNum,tickets[selectNo-1].colNum,tickets[selectNo-1].movieTicketPrice,tickets[selectNo-1].place);
    
    //打印座位信息表!
    for(int i=-1;i<ROW;i++)
    {
        for (int j=-1; j<COL; j++) {
            if((i==tickets[selectNo-1].rowNum-1)&&(j==tickets[selectNo-1].colNum-1))
            {
                printf(" @ ");
            }
            else
            {
                //else里面的代码直接可以复制上面
                if(i==-1)
                //i为0时,表示第1行,这时要将第-1行的位置写上列标
                {
                    printf("%02d ",j+1);
                }
                else if(j==-1)
                //j为0时,表示第1列,这时要将第-1列的位置写上行标
                {
                    printf("%02d",i+1);
                }
                else
                    printf(" + ");
            }
        }
        printf("\n");
    }

    
}

@end


——————————————————Cinema.m——————————————————

②allTicket文件夹

——————————————————Ticket.h——————————————————


#import <Foundation/Foundation.h>

@interface Ticket : NSObject

//地点
@property NSString * place;

//首映时间
@property NSString * showTime;

//放映开始时间
@property NSString *startTime;

//时长
@property int lengthTime;

//名称
@property NSString * name;

//导演
@property NSString * director;

//主演
@property NSString * actor;

//排数
@property int rowNum;

//座位号
@property int colNum;

//编号
@property int no;


@end


——————————————————Ticket.h——————————————————

——————————————————Ticket.m——————————————————


#import "Ticket.h"

@implementation Ticket

@end


——————————————————Ticket.m——————————————————

——————————————————MovieTicket.h——————————————————


#import "Ticket.h"

@interface MovieTicket : Ticket

//票价
@property float movieTicketPrice;

//电影票的编号(流水号)
@property int movieTicketNum;

@end


——————————————————MovieTicket.h——————————————————

——————————————————MovieTicket.m——————————————————


#import "MovieTicket.h"

@implementation MovieTicket

@end


——————————————————MovieTicket.m——————————————————


★整个项目就是这么简单,总得来说锻炼我们的不是基础知识,而是怎么构建这么一个框架的头脑,方方面面都要俱到。我们应该锻炼这种能力,让自己具备项目头脑。

It\'s  all !

版权声明:本文为博主原创文章,未经博主允许不得转载。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Objective-C市场占有率排名升至第4位发布时间:2022-07-12
下一篇:
[转]Objective-C的新特性发布时间:2022-07-12
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap