iOS程序员面试分类模拟4_第1页
iOS程序员面试分类模拟4_第2页
iOS程序员面试分类模拟4_第3页
iOS程序员面试分类模拟4_第4页
iOS程序员面试分类模拟4_第5页
已阅读5页,还剩2页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

iOS程序员面试分类模拟4简答题1.

什么叫多态?正确答案:多态(Polymorphism)在面向对象语言中指同一个接口可以有多种不同的实现方式,Objective-C中的多态则是不同对象对同一消(江南博哥)息的不同响应方式,子类通过重写父类的方法来改变同一消息的实现,体现多态性。另外,C++中的多态主要是通过virtual关键字(虚函数、抽象类等)来实现,具体来说指允许父类的指针指向子类对象,使其成为一个更泛化、容纳度更高的父类对象,这样父对象就可以根据实际是哪种子类对象来调用父类同一个接口的不同子类实现。

举个简单例子来展示Objective-C的多态实现。假设有一个动物父类Animal,其下有两个子类,一个是Dog,一个是Cat,父类有一个统一接口:shout,表示动物的叫声,父类对接口有一个默认实现,子类各自有自己的接口实现,继承关系如图所示。

父子类继承关系

Animal父类:

//Animal.h

@interfaceAnimal:NSObject

/*父类接口,动物叫声*/

-(void)shout;

@end

//Animal.m

#import"Animal.h"

@implementationAnimal

/*父类接口的默认实现,无语*/

-(void)shout{

NSLog(@"......");

}

@end

Dog子类:

//Dog.h

#import"Animal.h"

@interfaceDog:Animal

/*重写父类接口,狗叫声*/

-(void)shout;

@end

//Dog.m

#import"Dog.h"

@implementationDog

/*重写父类接口,狗叫声*/

-(void)shout{

NSLog(@"汪汪汪,汪汪汪");

}

@end

Cat子类:

//Cat.h

#import"Animal.h"

@interfaceCat:Animal

/*重写父类接口,猫叫声*/

-(void)shout;

@end

//Cat.m

#import"Cat.h"

@implementationCat

/*重写父类接口,猫叫声*/

-(void)shout{

NSLog(@"喵喵喵,喵喵喵");

}

@end

多态性测试:

/*1.指向Animal父类对象的Animal父类指针*/

Animal*p_animal4animal=[[Animalalloc]init];

/*2.指向Dog子类对象的Animal父类指针*/

Animal*p_animal4dog=[[Dogalloc]init];

/*3.指向Cat予类对象的Animal父类指针*/

Animal*p_animal4cat=[[Catalloc]init];

/*向指向不硎对象的父类指针发送相同的消息,期望得到各自不同的结果,实现多态*/

[p_animal4animalshout];

//打印结果:……

[p_animal4dogshout];

//打印结果:汪汪汪,汪汪汪

[p_animal4catshoutl;

//打印结果:喵喵喵,喵喵喵

2.

重载、重写和隐藏的区别是什么?正确答案:重载(overload):函数名相同,函数的参数列表不同(包括参数个数和参数类型),至于返回类型可同可不同。重载发生在同一个类的不同函数之间,是横向的。重载和多态性无关。

重写(override):主要指父类虚函数(虚函数是C++语言概念)的重写,用来体现多态性,指子类不想继承使用父类的方法,通过重写同一个函数来实现对父类中同一个函数的覆盖,因此又叫函数覆盖。重写的函数必须和父类一模一样,包括函数名、参数个数和类型以及返回值,只是重写了函数的实现。重写发生于父类和子类之间,是纵向的。

隐藏:Objective-C中没有隐藏,典型的C++中有,通过虚函数和父子类之间的函数重写进行区分,此处不再讨论。其中,重载和重写是针对函数的,而隐藏除了函数还会针对成员变量。隐藏发生在父类和子类之间,隐藏指父类的同名函数或变量在子类中隐藏,其中只要函数同名就隐藏,不管参数相同与否。在子类中父类的同名函数或变量不可见,但在父类中依然存在。

3.

Objective-C和Swift中有重载吗?正确答案:Swift中有重载,但Objective-C中基本不支持重载,事实上Objective-C支持参数个数不同的函数重载。

Swift是基于C语言和Objective-C语言优化后更加完善的新型语言,摆脱了C的兼容性限制,采用安全的编程模式并且增加了一些新的特性使编程更加有趣、友好,适应语言发展的趋势和期望。函数重载作为多态性的一个部分在Swift中是支持的,可能也是考虑到要弥补Objective-C中不完全支持函数重载的这一缺陷。Objective-C不完全支持重载,因为Objective-C学习者应该会发现同一个类中不允许定义函数名相同且参数个数相同的两个函数,无论参数类型和返回值类型相同与否。但是说完全不支持也太绝对,因为Objective-C中允许定义函数名相同但参数个数不同的两个函数,也就是说Objective-C支持参数个数不同的函数重载。例如,可以在一个类中定义两个参数个数不同的函数,调用时通过参数个数进行区分。

重载函数定义如下:

-(void)test:(int)one;

-(void)test:(int)oneandTwo:(int)two;

重载函数实现如下:

-(void)test:(int)one{

NSLog(@"oneparameter!");

}

-(void)test:(int)oneandTwo:(int)two{

NSLog(@"twoparameters!");

}

多态调用:

[selftest;1];

//output:oneparameter!

[selftest:1andTwo:2];

//output:twoparameter!

可以看出Objective-C可以通过参数个数实现函数重载,但是如果参数相同,那么无论参数和返回值类型相同与否,都无法编译通过。下面的定义是无法通过Xcode编译的。

-(void)test:(int)one;

-(int)test:(float)one;

//Duplicatedeclarationofmethod'test'

4.

Objective-C的类可以多重继承吗?可以实现多个接口吗?重写一个类的方式用继承好还是类别好?为什么?正确答案:Objective-C的类只支持单继承,不可以多重继承。

Objective-C可以利用protocol代理协议实现多个接口,通过实现多个接口完成类似C++的多重继承。在Objective-C中多态特性是通过protocol(协议)或者Category(类别)来实现的。protocol定义的接口方法可以被多个类实现,Category可以在不变动原类的情况下进行方法重写或者扩展。

重写一个类一般情况下使用类别更好,因为用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关系。

5.

Cocoa中有虚基类的概念吗?正确答案:Cocoa中没有虚基类的概念。虚基类是C++语言中为了解决多重继承二义性问题的,而Objective-C中只有单继承。

要实现类似C++语言中的多继承,可以通过protocal来简单实现,因为一个类可以实现多个协议,类似于Java中一个类可以实现多个接口。

6.

什么是编译时与运行时?正确答案:编译时:即编译器对语言的编译阶段,编译时只是对语言进行最基本的检查报错,包括词法分析、语法分析等,将程序代码翻译成计算机能够识别的语言(例如汇编等),编译通过并不意味着程序就可以成功运行。

运行时:即程序通过了编译这一关之后编译好的代码被装载到内存中运行起来的阶段,这个时候会对类型进行检查,而不仅仅是对代码的简单扫描分析,此时若出错程序会崩溃。

可以说编译时是一个静态的阶段,类型错误很明显可以直接检查出来,可读性也好;而运行时是动态的阶段,开始具体与运行环境结合起来。

7.

所谓的Objective-C是动态运行时语言是什么意思?正确答案:Objective-C是动态运行时语言主要指Objective-C语言的动态性,包括动态性和多态性两个方面。

动态性即Objective-C的动态类型、动态绑定和动态加载特性,将对象类型的确定、方法调用的确定、代码和资源的装载等推迟到运行时进行,更加灵活。

多态是面向对象变成语言的特性,Objective-C作为一门面向对象的语言,自然具备这种多态性。多态性指来自不同类的对象可以接收同一消息的能力,或者说不同对象以自己的方式响应相同的消息的能力。

8.

对于语句NSString*testObject=[[NSDataalloc]init];,testObject在编译时和运行时分别是什么类型的对象?正确答案:testObject是一个指向某个对象的指针,不论何时指针的空间大小都是固定的。

编译时:指针的类型为NSString,即编译时会被当成一个NSString实例来处理,编译器在类型检查的时候,如果发现类型不匹配则会给出黄色警告,由于该语句给指针赋值用的是一个NSData对象,所以编译时会给出类型不匹配警告。但编译时如果testObject调用NSString的方法,那么编译器会认为是正确的,既不会警告也不会报错。

运行时:运行时指针指向的实际是一个NSData对象,因此如果指针调用了NSString的方法,那么虽然编译时通过了,但运行时会崩溃,因为NSData对象没有该方法。另外,虽然运行时指针实际指向的是NSData,但编译时编译器并不知道(前面说了编译器会把指针当成NSString对象处理),因此如果试图用这个指针调用NSData的方法,那么会直接编译不通过,给出红色报错,程序也运行不起来。

9.

Objective-C中的id类型指的是什么?id、nil代表什么?正确答案:id表示Objective-C对象的类型在编写代码时(编译期)不确定,视为任意Object类型(即指向任意继承了NSObject的类的对象或者NSObject对象的指针),直到程序运行起来时才最终确定其类型。

id类似于C/C++中的void*,但id和void*并非完全一样。id是一个指向继承了NSObject的Objective-C对象的指针,注意id是一个指针,虽然省略了*号。id和C语言的void*之间需要通过bridge关键字来显式的桥接转换。具体转换方式示例代码如下:

idnsobj=[[NSObjectalloc]init];

void*p=(__bridgevoid*)nsobj;

idnsobj=(__bridgeid)p;

Objective-C中的nil定义在objc/objc.h中,表示一个指向空的Objctive-C对象的指针。例如weak修饰的弱引用对象在指向的对象释放时会自动将指针置为nil,即空对象指针,来防止指针悬挂。

10.

instancetype和id有什么区别?为什么返回类的实例的类方法或实例方法使用instancetype而不是id?正确答案:instancetype和id都可以用来代表任意类型,将对象类型的确定往后推迟,用于体现Objective-C语言的动态性,使其声明的对象具有运行时的特性。

它们的区别是:instancetype只能作为返回值类型,但在编译期instancetype会进行类型检测,因此对于所有返回类的实例的类方法或实例方法,建议返回值类型全部使用instancetype而不是id;id类型既可以作为返回值类型,也可以作为参数类型,也可以作为变量的类型,但id类型在编译期不会进行类型检测。

11.

id,NSObject,id<NSObject>的区别是什么?正确答案:NSObject修饰的对象肯定是NSObject对象,但id修饰的对象虽然肯定是Objective-C对象,但不一定是NSObject对象,id类型是一种运行时的动态类型,编译器不会对其进行类型检查。id<NSObject>修饰的对象也是一种动态类型对象,对象的类型在运行时才确定,但编译器知道它一定是遵守NSObject协议的。例如:id<NSObject>常用来定义delegate对象。

idfool;

//是Objective-C对象,但不是NSObject对象

NSObject*foo2;

//NSObject对象

id<NSObjec

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论