Objective-C 【完整OC项目-购票系统-系统分析-代码实现】
电影院买票系统/演唱会买票系统
需求分析:
首先我们进入系统,然后会选择买电影票还是买演唱会票,所以这牵扯两个系统的合成。但是我们知道都是买票系统,所以我们可以先创建一个类,属于购买电影票和演唱会的票的共同点,我们可以创建一个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 !
版权声明:本文为博主原创文章,未经博主允许不得转载。
Objective-C 【完整OC项目-购票系统-系统分析-代码实现】的更多相关文章
- 用Swift重写公司OC项目(Day1)--程序的AppIcon与LaunchImage如何设置
公司之前的APP呢经过了两次重写,都是使用OC由本人独立开发的,不过这些东西我都不好意思说是自己写的,真心的一个字:丑!!! 客观原因来说主要是公司要的特别急,而且注重的是功能而非效果,公司的美工之前 ...
- OC-《购票系统》
来个命令行的购票系统 --1-- 需求分析 1.1 分析 1.2 功能分析 1.3 流程分析 --2-- 原型展示 2.1 界面原型 --3-- 系统设计 3.1 类设计 3.2 框架模块设计 --4 ...
- 在OC项目工程中混编Swift
1.创建一个OC项目工程,然后在Build Settings中找到如下字段,修改. 2.然后在项目中创建swift文件,如果系统提示是否需要创建桥接文件的时候,点击确定. 然后在Build Setti ...
- react + redux 完整的项目,同时写一下个人感悟
先附上项目源码地址和原文章地址:https://github.com/bailicangd... 做React需要会什么? react的功能其实很单一,主要负责渲染的功能,现有的框架,比如angula ...
- 将React Native 集成进现有OC项目中(过程记录) 、jsCodeLocation 生成方式总结
将RN集成到现有OC项目应该是最常见的,特别是已经有OC项目的,不太可能会去专门搞个纯RN的项目.又因为RN不同版本,引用的依赖可能不尽相同,所以特别说明下,本文参考的文档是React Native ...
- VM Depot 镜像新增系列III – 社交媒体,内容管理 与 项目协同系统
发布于 2014-06-30 作者 刘 天栋 对于架设可协同作业的网站平台, Windows Azure有着得天独厚的优势.这不仅在于其强大的扩展性和安全性,更重要的是 Azure 平台对各类 ...
- 一个完整的项目中,需要的基本gulp
一个完整的项目需要使用gulp的多种功能,包括—— (1)加载各种需要的插件 var concat=require('gulp'); var clean=require(''gulp); 等等.需要的 ...
- asp.netmvc 三层搭建一个完整的项目
接下来用 asp.net mvc 三层搭建一个完整的项目: 架构图: 使用的数据库: 一张公司的员工信息表,测试数据 解决方案项目设计: 1.新建一个空白解决方案名称为Company 2.在该解决方案 ...
- KJMusic完整音乐项目
KJMusic完整音乐项目 KJMusic是一个完整音乐项目,这个项目从欢迎页面到首页以及音乐播放页面都做得非常不错.并且本音乐支持本地音乐,和音乐电台,支持切换上下首个.本项目还支持侧滑出现menu ...
随机推荐
- 无线路由器的“克隆MAC地址”是干什么作用的?
本文章转载:http://blog.sina.com.cn/s/blog_4c900d100102uysb.html 1.问题: 无线路由器的“克隆MAC地址”是干什么作用的?怎样使用? 2.使用背景 ...
- QM课程03-采购中的质量管理
QM模块被包含于采购过程的下列决策制定阶段:查询.供应商选择.采购订单.货物订单.收货.收到检查和收货数量的下达. 供应商下达 质量部门为一种被指定的物料下达一个供应商,它可以限制或限定下达的数量.如 ...
- URAL 2048 History 蔡勒公式
HistoryTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view.acti ...
- URAL 2046 A - The First Day at School 模拟题
A - The First Day at SchoolTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudg ...
- java 覆盖hashCode()深入探讨 代码演示样例
java 翻盖hashCode()深入探讨 代码演示样例 package org.rui.collection2.hashcode; /** * 覆盖hashcode * 设计HashCode时最重要 ...
- Android使用百度定位SDK 方法及错误处理
之前我的项目中的位置定位使用的是基站方法,使用的Google提供的API,但是前天中午突然就不返回数据了,到网上搜了一下才知道,Google的接 口不提供服务了,基于时间紧迫用了百度现有的SDK,但是 ...
- js判断图片是否显示
function getDefaultImg() { //添加判断图片是否存在操作 var $defaultImgPathObj = $('input[name=defaultImgPath]'); ...
- MySQL · 特性分析 · innodb 锁分裂继承与迁移
http://mysql.taobao.org/monthly/2016/06/01/ innodb行锁简介 行锁类型 LOCK_S:共享锁 LOCK_X: 排他锁 GAP类型 LOCK_GAP:只锁 ...
- Java_maven构建项目(多模块项目)
在eclipse下构建maven项目,该项目由多个子模块组成. 1.创建一个父项目 NEW -->project-->maven-->maven Project,点击下一步,进入ne ...
- 称球问题(zt)
下面说的这个问题可能大家都看到过,它是这么描述的: 现在有n(n>=2)个球,n个球外观一模一样,但是重量有区别,其中有且仅有一个球的重量比其它n-1个球要重,现在有一个天平,天平是完好无损的, ...