现在的位置: 首页 > 综合 > 正文

iphone开发的基础二类的实现

2018年05月13日 ⁄ 综合 ⁄ 共 2310字 ⁄ 字号 评论关闭

           接着上文来说,上面我们是定义了一个接口的定义,下面我们来实现它,object c中的类文件使用扩展名m.  

Fraction.m
#import "Fraction.h"
@implementation Fraction
-(void) setNumerator: (int) n{
numerator=n;
-(void) setDenominator: (int) d{
denominator=d;
}
-(void) setNumerator: (int) n andDenominator: (int) d{
numerator=n;
denominator=d;
}
-(int) numerator{
return numerator;
}
-(int) denominator{
return denominator;
}
-(void) print{
printf("%d/%d\n",numerator,denominator);
}
-(void) m{
printf("-m:The class variable t is %d\n",++t);
}
+(void) t{
printf("+t:The class variable t is %d\n",++t);
}
@end


因为我们将Fraction.m 与Fraction.h 放在一个文件夹下面,所以#import 使用了” ”,这个类的
任务就是实现接口中的方法,因此与接口的结构不同的地方就是,你不能在这里定义变量,
@interface 换成了@implementation,其余就没有什么特别的了。你不必在这里实现@interface
中的全部方法,这不会导致错误。这里有个-(void) m 方法比较特别,我们并没有在@interface
中声明,那么这个方法可以调用吗?因为Object-C 是动态语言,即便是@interface 中没有定
义的方法,依然可以被调用。
另外,你需要注意的是setter 方法与接口中不同的是参数名缩写成了n、d,这是因为在方
法中,本地变量(参数、方法中定义的变量)在名称冲突的情况下,会隐藏成员变量,因此
导致numerator=numerator 变成了无意义的操作。当然你可以使用后面提到的self 关键
字,写成 self->numerator=numerator,也就是JAVA 中的常用的this.x=x 的写法。

     下面我们编写调用代码,因为Object-C 基于C 语言,所以程序的入口依然是main 函数。这
里注意#import 的是h,不是m。代码如下:
     

main.m

#import "Fraction.h"
int main(int argc,const char *argv[]){
Fraction *frac=[[Fraction alloc] init];
[frac setNumerator: 3 andDenominator: 5];
[frac print];
printf("The denominator of Fraction is %d\n",frac->denominator);
[Fraction t];//调用类方法
[frac m];
[frac release];
return 0;
}


(1.) 第一行我们创建了Fraction 的实例(对象),Object-C 中实例只能使用指针作为变量,而
不能使用值,所以你看到了*frac,而不是frac,这与JAVA 是一致的,JAVA 中的指向实
例的变量(JAVA 中叫做引用)也是指针,只不过JAVA 中没有指针的概念,所以你没有
看到*。至于等号右侧的创建实例的代码,你可以在下面看到,这里先不用理会。
(2.) 第二行代码调用同时设置两个变量的方法,我们看到Object-C 的调用方法的语法格式为
[类或者实例的指针 方法名: 参数1 标签1: 参数2… …]。这种调用格式被称为中缀
语法,初次看起来有点儿怪,但实际这样更加有效。举个例子,你接手了一个离职的人
程序,其中的JAVA 程序调用了一个有五个甚至更多的参数的方法,但是你手里没有这
个方法的API,那么你很难猜得出来这五个参数到底都干什么用的,但是Object-C 调用
的时候,每个参数前面都必须有方法的标签名,这样你便能很容易的从标签名看出这个
参数是什么意思。
(3.) 第四行在C 的printf()函数中使用了对象->成员变量的语法访问实例的变量,但一般我
们不推荐这么做,而是使用getter 方法。这里你不能访问numerator 变量,因为它是
@protected 的,只能本类、子类直接访问。
(4.) 第五行我们调用了类方法t,你也可以换成这样的写法:
[[Fraction class] t];
或者
Class clazz=[Fraction class];
[clazz t];
class 方法是一个类方法,来自于NSObject,相当于JAVA 中的getClass()方法,也就是获
取这个类的Class 对象,clazz 前面没有*。另外这种嵌套调用的方式,你也要习惯,这就
和JAVA 中的A.b().c()没有什么区别。

(5.) 第六行我们调用了m 方法,这个方法你会发现并没有在@interface 中声明,这里依然调
用了,只是在编译的时候收到一个警告。这就是前面所有的Object-C 是动态语言的原因。
但是一般情况下,你都会给别人提供h 文件,所以你在m 文件中写的h 文件中没有的
方法,别人也是不会知道的,这个方法相当于变相的私有化了。

(6.) 第七行我们释放了frac 实例在第一行alloc 所申请的内存空间,Object-C 的内存管理后面
会看到。另外,你会发现Fraction.h 中没有定义alloc、init、release 方法,但是我们上面
调用了,很显然,这些方法来自于父类NSObject。

抱歉!评论已关闭.