Objective-C 编程语言(2) 类,对象,消息 --- 类(1)继承


面向对象的程序通常都是有各种各样的对象构成的。基于Cocoa框架的程序可能用到了NSMatrix对象,NSWindow对象,NSDictionary对象,NSFont对象,NSText对象以及其他的许多种类的对象。程序中通常也是使用某个类的多个对象,而不是一个。比如,多个NSArray类的对象或者是多个NSWindow类的对象。

在Objective-C中,通过定义对象所属的类来定义对象。类是一种类型对象的原型。其中声明了属于该类的每个对象的成员变量,并定义了该类所有对象都能使用的方法。

编译器只会为一个类创建一个可以访问的对象,那就是类对象。类对象知道如何去生成该类的对象。正是基于这种原因,类对象通常都会被称为是工厂对象。类对象是类在编译时期的版本。类对象生成的对象才是类的实例。程序中进行实际工作的都是由该类对象创建出来的实例对象。

类的所有实例共有一套方法集,但是各自都含有自身的实例变量。每一个对象的实例变量是自己独有的,但是所有方法是共享的。

按照惯例,类名称首字母一般是大写的,例如Rectangle。实例变量的名称首字母通常是小写的,如myRectangle。

继承

类的定义是具有追加性的。每一个从其他类派生而来的新类都继承了其中的方法和实例变量。新的类知识简单地对这些继承的东西进行追加或者修改,而不需要复制其对应的代码。

继承把所有的类都关联起来,从而形成一个具有唯一一个根节点的继承关系图。当编写基于“Foundation framework基础框架”的程序的时候,这个跟类就是NSObject。继承图中出了跟类之外的所有类都有一个超类,这个超类在继承关系图上距离跟类更进一步。任何类,包括跟类都可以是多个类的超类,其子类在继承关系图上距离跟类更远一步。图1-1展示了在绘图程序中可能用到得类的继承关系图:


从上图中可以看出Square类是Rectangle类的子类;Rectangle类Shape类的子类;Shape类是Graphic类的子类;Graphic类是NSObject类的子类。 继承关系具有累积性。因此,Square类的对象拥有在Rectangle类,Shape类,Graphic类已经NSObject类中定义的方法以及实例变量。当然Square类的对象拥有在Sqaure类自身中定义的实例变量和方法。简而言之,一个Square类的对象不仅仅是一个方形(square),同时也是一个矩形(rectangle),也是一个形状(shape),也是一个图形(Graphic),还是一个对象(NSObject)。

除了NSObject类之外的每一个类都可以被看做是对其超类的具体化。其后的每一个子类都是对这种累积继承的修改。Square类中定义的只是把一个矩形rectangle变成是一个方形所需的最小修改。

在定义类的时候是通过声明其超类来把该类连接到类的继承关系图中的。我们创建的每一个类都应该是另外一个类的子类,除非我们想要定义的是跟类。其中可选的超类是很多的。Cocoa中包含了NSObject以及几个框架。其中就包含了超过250多种的类。其中有很多类是我们可以直接拿来在我们的程序中使用的。还有一些其他的类,我们可以根据我们的需要,通过定义其子类来对其进行修改。

上面说到的一些框架类几乎定义了我们所需的全部东西,但是把某些详细的实现留个了子类。因此我们只需要根据我们的需要编写少量的代码,而复用这些已有的东西来快速地编写出可靠的代码。

NSObject类

NSObject类是一个跟类,他不需要超类。其中定义了Objective-C中的对象以及对象交互所需的基本框架。通过继承NSObject类,这种对象的行为能力以及与运行时交互的能力在其子类中传播

开来。

不需要从别的类中继承特殊行为的类至少应该是NSObject类的子类。因为该类的实例至少在运行时应该具有Objective-C对象所具有的基本能力。从NSObject类继承这种能力和在新类中重新定义这些能力先比则更简单并且更可靠。

注意:实现一个全新的跟类是一件十分复杂的任务,并且具有潜在的危险性。该类必须重复在NSObject类中已经完成的大量工作。比如分配实例,并把它与对应的类相关联,并在运行时对其进行鉴别等。正是如此,我们应该使用Cocoa中提供的NSObject类来作为跟类。更多信息参见《NSObject 协议参考》一书中的“NSObject 类参考”章节。

继承实例变量

当一个类对象创建一个新的实例的时候,该实例不仅含有其类中所定义的实例变量,还含有其类的超类中所定义的实例变量,还含有其超类的超类中所定义的实例变量,这样依此类推知道根类。这样以来NSObject类中定义的实例变量就成了所有对象都拥有的变量。正是isa 把一个对象和其对应的类联系起来了。

图1-2展示了一种可能的Rectangle类的实现,其中包含包含了Rectangle类中定义的变量,Shape类中定义的变量,Graphic类中定义的变量以及NSObject类中定义的变量。


类中定义实例变量并不是必要的。一个类可以只定义新的方法,而完全依靠继承而来的那些实例变量。例如,Square类自身中就可以不用定义任何实例变量。

继承方法

对象不仅可以访问其类中定义的方法,还可以访问其超类中定义的方法,以及其超类的超类中定义的方法,依此类推知道根类。例如,Square类的对象就可以使用Rectangle类,Shape类,Graphic类以及NSObject类中定义的方法。

因此,程序中的新定义的类可以复用在继承关系图图中位于其上方的所有超类的代码。这种继承机制是面型对象编程的一个很重要的好处。当我们Cocoa提供的面向对象的框架类的时候,我们的程序就可以利用这些已经为该框架类编写好的代码功能。我们在程序中只需要根据需要增加一些代码来完成特性的功能。

在继承关系图中,类对象也继承了位于其上方的超类。但是由于类对象没有实例变量,因此他们只是继承了方法。

方法的覆盖

继承机制中有一个很有用的特殊情况:在定义新的类的时候,我们可以在新的类中实现在继承关系图途中和其超类中同名的函数。这个新的方法就覆盖了原来的方法。新的类的实例将执行的是该新的方法而不是原来的方法。该新类的派生类继承的也将是该新的方法而不是原来的方法。

例如,Graphic类中定义了display方法,而在在Rectangle类中是可以通过定义新的display的实现而覆盖继承而来的原有的display方法。Graphic类中的方法对于它的所有派生类都是可用的,而Rectangle类除外,Rectangle类将执行的是自身的Rectangle类的display方法。

尽管这种覆盖机制可以阻止原来的方法被继承,但是新类中的其他方法却是可以跳过这个新的方法而使用原来的方法的。更多信息参见“向self和super发送消息”章节。

新定义的方法中是可以使用被他覆盖的原来的方法的。此时,新的方法是对原有方法的更新或者是修改,而不是对其进行完全的替换。当继承关系图中的多个类都定义了同样的方法,但是如果每一个的实现都使用到了被覆盖的原来的方法的话,原来方法中的实现便会在这些类中蔓延开来。

尽管派生类是可以覆盖继承而来的方法的,但是派生类不能覆盖继承而来的实例变量。这是因为在为对象分配空间的时候,是为对象的每个实例变量,包括继承而来的实例变量都要分配空间。因此不能企图通过在派生类中定义与超类中同名的实例变量来覆盖超类的实例变量。如果确实遇到了这样的代码,编译时,编译器会报告告警或者错误的。

抽象类

一些类在设计的时候就是希望被别的类继承。这种抽象的类只是方法和实例变量组合起来,以便于可以被更加通用的派生类使用。这种抽象类自身是不完全的,但是含有能够减轻其派生类代码负担的有用代码。由于抽象类必须有派生类才显得有意义,因此它们有时会被成为抽象的超类。

与其他的语言不同的是Objective-C语言中没有专门的语法来标识一个类是抽象类,因此也不会阻止我们在程序中创建抽象类的实例。

在Cocoa中,NSObject类就是公认的这样的抽象类。在程序中我们是不会直接使用到NSObject类的实例的。因为这样做没有任何用,这样的对象将是一个泛化的对象,他没有任何具体的功能    。

NSView类也是抽象类的一个例子。该类的实例可能会被偶尔使用到。

抽象类中通常含有的是用于定义程序结构的代码。当我们定义这些抽象类的派生类的以后,这些派生类可以很方便地适应程序框架工作,并自动地相互配合工作。

下图为今年部分iOS开发的视频教程,因为不定时更新中故不做多的截图,如果有iOS开发上的问题不懂或者需要视频教程可以看我的个人简介。

因为三月还没结束,故不截图,不定时更新中。


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

推荐阅读更多精彩内容