分数类
第一个Objective-C程序
这一期,我们就来正式的打出第一个具有Objective-C味道的程序。没错,如果你觉得前面几期太easy了,和C没有区别,那么以后就是和C有不同的地方的内容了。
在学习新的一期之前,还是建议回去复习一下前两期的内容。
第二期:https://www.jianshu.com/p/0bd7e58147e0
第一期:https://www.jianshu.com/p/5c27421e8828
Objective-C程序特点
Objective-C的结构主要分以下几个部分:
- @interface部分
- @implementation部分
- 程序部分
1.@interface部分
@interface,顾名思义就是接口的意思,其主要作用就是定义一个新的类。
其格式为:
@interface NewClassName:ParentClassName
类的属性和方法的声明;
@end
这里就体现了面向对象编程的第一个特性「继承」,输入这么样的一个语句后,新创建的类就从原来已知的一个类继承过来,也就是说新的类具有该原来的类的属性和方法。
接下来就有两个定义:
父类:原来就存在的类,被子类所继承。
子类:新产生的类,具有父类的特性。
2.@implementation部分
@implementation,顾名思义,也就是实现的意思。
这个部分主要将@interface中声明的方法,给出定义,(也就是说把方法添加实际的代码)并指定类对象中存储的数据类型。
其一般格式如下:
@implementation NewClassName
{
成员声明;
}
方法定义;
@end
3.程序部分
程序部分就不用说了,就和前两期的代码类似,必须要有一个主函数,然后在主函数里,你可以像第二期一样,创建对象,并对对象进行操作。
下面我就准备用书中的例子来解释一下,我所讲的概念,而且这个例子中有很多的扩展部分,注意记好笔记。
在写例子之前有些注意事项需要注意一下。
注意事项
关于类的命名问题
类的命名基本上和C的变量命名类似,注意以下几点:
- 必须以字母或下划线(_)开头,之后可以是字母、下划线或数字
- 不能有其他非法字符
- 不能使用系统保留字命名
- 名称中间不能有空格
- 如要表达空格,可以用下划线代替,这种方法有一个很非正式的说法叫做:驼峰命名法。例如,play_the_piano。
给类命名时,要用大写;
给对象和方法命名时,要用小写;
如果名字中含有多个词,要用大写区分开来,比如:goToHell。
虽然命名没什么硬性规定,但是这样的规定可以增加程序的可读性。学C的也是可以套用这些命名的规则的。
其次,就是类方法和对象方法。方法其实说白了就是函数。
看看它的格式就知道了:
类方法:
+(返回值类型) 方法名:(参数类型)参数名称
对象方法:
-(返回值类型) 方法名:(参数类型) 参数名称
和函数的定义基本就很像了,就是用「+」和「-」区分类方法和对象方法而已。
分数类(Fraction Class)
书中用了一个分数类来解释OC编程中可能遇到的问题
问题
用面向对象的方法来编写一个显示分数的程序。
分析
如果我们要创建一个分数类,然后实例化形成对象,我们应该进行怎样的操作呢?
一个分数要有分子(numerator)和分母(denominator),所以我们就先命名两个变量叫做分子和分母。
然后我们要给分子、分母赋值,所以要创建两个赋值方法。
最后,你会发现,分母、分子已经附好值了,却编译运行的时候啥也没有,GG,所以你要给它一个打印方法。
代码
#import <Foundation/Foundation.h>
@interface Fraction:NSObject
-(void) print;
-(void) setNumerator;
-(void) setDenominator;
@end
@implementation Fraction
{
int numerator;
int denominator;
}
-(void) setNumerator
{
NSLog(@"请输入分子");
scanf("%i",&numerator);
}
-(void) setDenominator
{
NSLog(@"请输入分母");
scanf("%i",&denominator);
}
-(void) print
{
NSLog(@"分数为:%i/%i",numerator,denominator);
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Fraction *frac1 = [Fraction new];
[frac1 setDenominator];
[frac1 setNumerator];
[frac1 print];
}
return 0;
}
代码解析:
@interface Fraction:NSObject
首先,这TM就很奇怪了,NSObject是什么鬼?
这个嘛,不用了解太多,只要知道NSObject就是OC里一个类似上帝般的存在就行了,你所命名的子类都是基于这个类。
这串代码就是说,我们在这个代码里进行了对类的创建。
-(void) print;
-(void) setNumerator;
-(void) setDenominator;
这是声明了分析里面三个对象方法,毕竟一个具体的分数就是一个对象嘛!
可能你会想到,分子和分母算是分数的属性,但是书里边给出的例子,并没有把分子分母写成属性,主要是因为在@interface中的属性变量是受保护的,如果应用到程序中,你会发现这些属性无法使用。(解决方法我们后期再讲,知道属性变量是受保护的就行)
@interface部分结束后,不要忘记写个@end哦。
@implementation Fraction
对分数类进行个实现
@implementation Fraction
{
int numerator;
int denominator;
}
这也就对应了上面的成员变量定义了,每生成一个对象,它就会有完全不同的numerator和denominator。
- (void) setNumerator
{
NSLog(@"请输入分子");
scanf("%i",numerator);
}
嗯,这是个对新手不太友好的教程,不过这确实是我根据原来的代码改进的,因为C和OC可以混用,所以我就用了scanf()来输入分子分母了,而不是像原来那样,要设参数,到时候还要自己在程序里输入一个在方法后面输入一个具体的参数。
-(void) print
{
NSLog(@"分数为:%i/%i",numerator,denominator);
}
如果不创建print这个方法,直接到程序里去NSLog,你会发现没有办法访问对象里的数据,从而就没有办法显示分数了。
写完方法后,记得@end哦
最后就是程序部分了
Fraction *frac1 = [Fraction new];
语句解释:创建一个叫做frac1的对象
创建对象的格式如下:
类名 *对象名 = [类名 new];
对新手满满的恶意233
先解释一下,「Fraction *frac1」中,(*)表示,frac1是Fraction对象的引用(或指针)。变量frac1实际上不存储Fraction的数据(即分数的分子和分母),而是存储了一个引用(其实是内存地址),表明对象数据在内存中的位置。frac1并没有任何值。
这句话是书中抄过来的,比较让我纳闷的是这个引用,是C++里的引用吗?
不过如果用指针理解还是挺easy的。反正就是说这个就是字面的意思了,没什么好说的。
[类名 new];
这个用了一个叫做new的类方法,不过这个new哪来的,当然是从之前说过的万能的上帝NSObject里来的。
当然如果你想知道new经历哪些过程,你可以看如下解释:
\\[Fraction new]相当于[[Fraction alloc] init]
\\[[Fraction alloc] init]还可以写成
先[Fraction alloc],再[Fraction init]
所以说创建一个对象就有从代码层面来说就是alloc分配一块内存,init初始化。
要注意的是,当你分配过后,此时init是对对象(frac1)发送的命令,而不是对类(Fraction)发送的命令。
[frac1 setDenominator];
[frac1 setNumerator];
[frac1 print];
这就没啥技术含量,既然有对象了我们就要「搞」事情嘛
如果你记得昨天的[Tom goDie]的话,你就知道是什么意思了。就是让对象去执行里边的方法。
最后我输出的结果就是这样的
今天的内容就是初步的体验一下,用OC面向对象编程,理解下昨天所说的对象和类。
小结:
看完之后,请问自己以下几个问题:
一个OC程序的结构是怎样的?
如何创建一个类?
如何声明方法,类方法和对象方法的区别是什么?
命名变量、对象时要注意什么?
如何创建一个对象?
小剧场
垂死挣扎的C语言要出来抢个戏,不就是显示个分数吗?你这太麻烦了
#include <stdio.h>
int main(int argc, const char * argv[]) {
int numerator;
int denominator;
printf("请输入分子\n");
scanf("%d",&numerator);
printf("请输入分母\n");
scanf("%d",&denominator);
printf("分数为%d/%d\n",numerator,denominator);
return 0;
}
C:多简单,多粗暴啊。OC你学着点。
OC:来来来,你头铁你写个图形界面试试。
C:.............
这一章比较卡,再出一期我就能结束了。
下回预告:set方法和get方法