Saturday, July 17, 2010

赶个时髦,学习一下Object-C

(未完)
由于iPhone等Mac系产品无比红火的存在,Object-C也变得重要起来。Object-C是Apple的御用语言(类似C#之于Microsoft)。如果要开发个iPhone App啥的,就需要用到Object-C。如果要在MacOS里写点基于Cocoa的应用程序,也需要用到Object-C(其实Cocoa有python等其他语言的绑定,不过我试了一下不太喜欢)。

话说当年水果教教主Steve Jobs被董事会一脚踢出了自己创立的Apple,就搞了一个Startup叫做NeXT。Object-C就是NeXT从别人手里买下的。Steve Jobs在NeXT待了十年,期间潜心研发硬件软件,修为大为精进。而Apple这段时间却止步不前,终于在1997年被Steve Jobs夺舍而复辟回到了Apple。Steve Jobs顺道也把在NeXT修炼的OpenStep操作系统(打包了Object-C,Cocoa和Xcode等)带回了Apple,也就是后来广为人知的MacOS X。在使用Object-C的时候会发现大量NS开头的类(NeXTstep的意思),就是在纪念这段历史。

Object-C从名字上来看顾名思义就是包括了面向对象的C。道友可能会问,C++不就是用面向对象版的加强的C么?对,但其实现在我们看到的C++是那轮改造中涌现出来的最流行的那个。Object-C和C++都说自己继承了C语言,是C的超集--当你用不到面向对象的时候确实是这样。但是用上面向对象以后,两者的语法就存在着不小的区别。Object-C的面象对象部分其实处处都流露出从更加上古时期就流传下来的Smalltalk的影子。为了以示区别,Object-C中对于C扩充的关键字多以@开头,比如@interface,@end等。

下面开始步入正题:
第一个Object-C程序:Hello World

像学习其他所有语言一样,我们也不能免俗的从Hello World开始。下面是Object-C版本的Hello World
#import <stdio.h>

int main( int argc, const char *argv[] ) {
    printf( "hello world\n" );
    return 0;
}
不难发现,Object-C的Hello World和C版本的基本一样,唯一区别在于把#include换成了#import。没错,谁让Object-C就是C的扩充呢。

面向对象:类的创建

在Object-C当中, 首先用@interface定义一个类的成员变量和成员函数,然后在@implement中实现成员函数
Object-CC++
//Foo.h
@interface Foo : NSObject 
{ 
@private:
    double x;
@protected:
    double y;
@public:
    double z;
} 
-(int) f:(int)x; 
-(float) g:(int)x :(int)y; 
@end
//Foo.h
class Foo 
{ 
private:
    double x;
protected:
    double y;
public:
    double z;
    int f(int x); 
    float g(int x, int y); 
};
//Foo.m
#import "Foo.h"
@implementation Foo 
-(int) f:(int)x {...} 
-(float) g:(int)x :(int)y {...} 
@end 
//Foo.cpp
#include "Foo.h"
int Foo::f(int x) {...} 
float Foo::g(int x, int y) {...}

调用类方法

Object-CC++
[myObj method]
[myObj method:para1:para2]
output=[myObj method:para1:para2]
[obj1 func1:[obj2 func2]]
myObj.method()
myObj.method(para1,para2)
output=myObj.method(para1,para2)
obj1.func1(obj2.func2())
在Object-C当中,类方法的调用并不是传统的C/C++方式。而是采取了贴近Smalltalk的设计--消息。

Instance Method vs Class Method
在Object-C中,类的方法分为Instance 和Class两种,定义的时候分别使用"-"以及"+". Class method在大多数其他语言比如C++以及Java中又叫静态方法(static method).
@interface MyClass : NSObject

+ (void)aClassMethod;
- (void)anInstanceMethod;

@end
调用的时候
[MyClass aClassMethod];

MyClass *object = [[MyClass alloc] init];
[object anInstanceMethod];

Duck Typing

同受Smalltalk影响,Object-C和Python一样可以归入Duck Typing:一个类的实例可以调用该类中定义都方法,也可以调用该类中并没有定义的方法。在C++中如果一个类foo没有定义方法bar,那么foo的实例是无论如何也不能调用bar的--编译就无法通过。但是在Object-C(以及Python)中却没有问题--至少在编译期没有问题,但在运行期会有异常.

参考

从C/C++语言到Objective-C语言
Learning Object-C

No comments: