第四章 对象的类型和动态绑定

动态绑定:程序在执行时才确定对象的属性和需要响应的信息。

多态:指同一操作作用于不同的类的实例时,将产生不同的执行结果。多态是面向对象的一个重要的特征,大大增强了软件的灵活性和扩展性。

把类作为类型去声明:NSObject *a;  nil表空对象,即这个对象的指针指向空,值为0。

将对象作为参数传递的时候,传递的并不是对象本身,而是指向对象的指针。

静态类型:将一个变量声明为特定类的对象,这种情况称为静态类型。使用静态类型时,编译器可以在编译时检查接受者是否可以响应收到的消息。

静态类型检查的总结:

对于id类型的变量,调用任何方法都能够通过编译。

id类型的变量和被定义为特定类的变量之间是可以相互赋值的。

被定义为特定类对象的变量(静态类型),如果调用了类或父类中未定义的方法,编译器就会提出警告。

若是静态类型的变量,子类类型的实例变量可以赋值给父类类型的实例变量。

若是静态类型的变量,父类类型的实例变量不可以赋值给子类类型的实例变量。

若要判断到底是哪个类的方法被执行了,不要看变量所声明的类型,而要看实际执行时这个变量的类型。

id类型并不是(NSObject*)类型

编程中类型的定义:

[ obj msg ] 消息表达式

obj是消息接收者,是一个对象。   msg是消息。

消息名又称为消息选择器,选择器,或方法。消息选择器中并不包含参数和返回值的类型信息,消息选择器和这些类型的信息结合在一起构成签名。签名被用于在运行时标记一个方法,接口文件中方法的声明也叫做签名。

如果消息接受者和参数类型是运行时确定的,那么消息签名不唯一的话编译就会出错。也就是说,objective-c中选择器相同的消息,参数和返回值的类型也应该相同。

类的前置声明:

当定义一个类的时候,有时会将类的实例变量,类方法的参数和返回值的类型来指定另一个类。这种情况有两种方法实现定义:

1.在新定义的类的接口文件中引入原有类的头文件。(该方法的缺点是头文件中除了类名还有其他信息的定义,此外还可能引入其他头文件,增加了编译时的负担如果仅仅是在类型定义的时候使用一下类名,则使用方法2来解决)

2.@class + 类名+”;",class指令后可以一次接多个类,中间用逗号隔开。该方法叫做类的前置声明。(@class可以提升程序的整体编译速度,而且当多个接口出现类的嵌套定义时如果只是包含对方的头文件无法解决,通过类的前置声明可以解决。但要注意的是,如果新定义的类要使用原有类的具体成员或方法,就一定要引入原有类的头文件)

强制类型转换:?

有些情况下必须使用强制类型转换,一个典型的例子就是父类类型的指针实际上指向了子类的变量。

(除了id之外,指针变量只能调用编译时类型的方法,不能调用它运行时的类型方法,故强转)

虽然强制转换的功能很强大,但会让编译器的类型检查变得没有意义,所以尽量少用。不得不用时,要重新思考设计是否合理。

实例变量的访问权限:

只能访问静态类型定义的实例对象的内部变量。因为能否访问实例对象的内部变量是需要经过检查的,该检查在编译期完成。

访问器:

OC不允许直接从外部访问和修改实例对象的属性,而仅仅可以访问同一个类的其他实例对象的变量,需要定义专门的方法来访问或修改实例变量:

getter方法(读取):从外部访问这个属性的方法应和属性同名。

setter方法(修改):定义修改该属性的方法时,用set做前缀,之后接要更改的属性的名称,属性名的首字母大写。

虽然子类的方法可以直接访问父类的实例变量,但我们要养成一个好的习惯,即尽量使用getter/setter 方法来访问父类中的实例变量,这样可以使程序做到尽可能的低耦合。

为什么不允许直接访问成员属性?一切都是为了封装,使程序尽可能地低耦合。

实例变量的可见性:

@private:只能在声明它的类内访问,子类不可以访问。可以在方法中通过->来访问同一个类的实例变量。

@protected:能够被声明它的类和任何子类访问。类方法中可以通过->来访问本类实例对象的实例变量。没有显式指定可见性的实例变量都是此属性。

@package:类所在的框架内可以像@public一样访问。而框架外则同@private一样,不允许访问。

@public:作用范围最大,本类和其他类都可以直接访问。

在实现部分中定义实例变量:

采用这种方法后,子类无法访问父类的实例变量。在实现文件中定义的实例变量的可见性默认是@private,也可用@public等来重设可见性。

所以让一个变量对外不可见有两种方法,一种是把变量的可见属性设为@private,另一种就是把变量定义在实现文件中。

类对象:

在OC中,对类的定义分为两部分,一部分定义所生成的实例的类型,另外一部分定义类自身的行为。

类本身也作为一个对象存在。类对象有自己的方法和变量,分别被称为类方法和类变量,在OC中,只有类方法的概念,没有类变量。至今为止我们一直把类的实例变量和方法称为实例变量和实例方法,这样可以和类变量和类方法进行区分。OC中类对象也被称为factory,类方法称为factory method。类对象是在程序运行时自动生成的。每个类只有一个类对象,不需要手动生成。类方法可以访问类对象管理的变量。

类对象的类型:

类对象可以用id类型来表示,也可以用OC为其专门定义的Class类型来表示。NSObject中定义了类方法class,所有类都可以用这个方法来获取类对象。除此之外,NSObject中还定义了实例方法class,所有的实例对象都可以使用class实例方法,这个方法返回的是对象所属类的类对象。

类名的使用:

将类名定义为消息接受者是类对象特有的功能,除此之外类名只能在类型定义时使用。

类方法的定义:

实例方法以“-”开头,类方法以“+”开头。类方法的一个典型操作就是创建类的实例对象,类对象收到alloc这种消息之后就会生成类的实例。继承情况下,子类可以访问父类的类方法。类方法不能访问类中定义的实例变量和实例方法。因为类对象只有一个,而类的实例对象有任意个,所以如果类对象可以访问实例变量,就会不清楚到底访问的是哪一个实例对象的变量。

其次,类方法执行时用self代表了类对象自身。

alloc是类方法,dealloc是实例方法。

类变量:

OC不支持类变量。OC通过在实现文件中定义静态变量的方法来代替类变量。继承情况下,可以通过定义类方法(getter,setter)来进行访问父类中定义的变量。

类对象的初始化:

OC的根类NSObject中存在一个initialize类方法,可以使用这个方法对各类对象进行初始化。每个类接收到消息之前,为这个类调用一次initialize,调用之前先调用父类的initialize方法。如果子类中没有实现initialize方法,其父类的initialize方法就会被调用两次,面向自己一次,面向子类一次。

初始化方法的返回值:

之所以将返回值类型定义为id,是因为考虑到初始化方法的返回值不是具体的类的类型,而是可变的,取决于上下文。例如父类初始化返回值定义为Volume*,则其子类调用父类初始化方法时返回的也是Volume。所以应将其定义为id。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,706评论 4 366
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,002评论 1 301
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,462评论 0 250
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,375评论 0 216
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,763评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,849评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,033评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,768评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,490评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,734评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,204评论 1 264
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,566评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,227评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,137评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,934评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,926评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,774评论 2 274

推荐阅读更多精彩内容