我们可以通过对父类的继承实现一定的扩展,继承主要有以下几种典型的用法:
1 代码复用。.两个类有部分相同的代码,那相同的部分我们就没必要去复制粘贴,完全就可以把公共的部分放在父类中,子类去继承,只需要实现一次相同的部分即可。
2.创建协议类。父类为子类规定了一些方法,哪怕是空的,但我们可以默认为父类为他的子类创建了一种协议,当不同的类实现同名的方法的时候,程序就可以采用多态的设计。
3.通用性能的发布。程序员可以定义一些基本的、通用的、可以解决某些问题的类,但是没有处理代码,那么其他的程序员可以创建子类来继承并且满足特定的需求。
4.需要对现有逻辑进行轻微改动。例如有个类在程序中的工作表现良好,但是另一个程序员想要修改其中的某些参数,那么他就可以继承这个类,并且在子类中修改而无需涉及到父类。
5.功能预览。子类可以帮助我们进行选择测试,实现父类的一些方法,
还有一个重点就是要记住,Obj-C中的继承是单继承,不支持多继承。
在Objective-C中super是指向直接父类的指针,而self是指向本身的指针,self就相当于java中的this指针。在OC中写类时可以在@implementation中定义哪些在@interface中无相应声明的方法,但这个方法是私有的,仅在类的实现中使用。
在Objectiv-C中几乎所有的类都是继承自NSObject类,NSObject类中存在大量功能强大的方法。下面对NSObject类中的各种方法进行试验和介绍:
1. +(void) load;
类加载到运行环境时调用该方法
测试:在子类中重写load方法来进行测试, 当重写完load方法,在mian方法中不需要任何实例化任何对象,当类被加载时load就会别调用.load是类方法,可以直接被类调用。
//重写NSObject中的load方法
+(void) load
{
NSLog(@"ObjectTest中的load方法被调用啦!!");
}
运行结果:2014-07-30 08:58:31.704 HelloOC[550:303] ObjectTest中的load方法被调用啦!!
2. +(void) initialize;
第一次使用该类时调用该方法,第二次就不调用了
测试:重写initalize方法
//重写initialize方法,会在类第一次使用时调用
+(void) initialize
{
NSLog(@"initialize方法被调用了(类第一次被实例化)!");
}
运行结果:
2014-07-30 09:27:53.767 HelloOC[624:303] load方法被调用啦!!
2014-07-30 09:27:53.769 HelloOC[624:303] initialize方法被调用了(类第一次被实例化)!
3. +(id) alloc:
返回一个已经分配好的内存对象;
-(id) init:
对已经分配了内存的实例进行初始化; new同时调用了alloc 和 init
demo: Object *object = [[Object alloc] init];
可以在子类中把alloc进行重写,然后观察运行情况
//重写alloc方法
+(id) alloc
{
NSLog(@"alloc函数被调用啦");
return [super alloc];
}
//重写init
-(id) init
{
NSLog(@"init被调用了");
self = [super init];
return self;
}
测试方法一个用alloc和init实例化类,一个用new实例化类:
//第一次使用ObjectTest类
ObjectTest *o1 = [[ObjectTest alloc] init];
//第二次使用ObjectTest类
ObjectTest *o2 = [ObjectTest new];
运行结果:
2014-07-30 09:59:58.991 HelloOC[689:303] load方法被调用啦!!
2014-07-30 09:59:58.993 HelloOC[689:303] initialize方法被调用了(类第一次被实例化)!
2014-07-30 09:59:58.993 HelloOC[689:303] alloc函数被调用啦
2014-07-30 09:59:58.993 HelloOC[689:303] init被调用了
2014-07-30 09:59:58.994 HelloOC[689:303] alloc函数被调用啦
2014-07-30 09:59:58.994 HelloOC[689:303] init被调用了
4.-(void)dealloc
释放对象自身所占有的内存;
5. -(Class)class 或者 +(Class)class 返回当前对象的所属类;
-(Class)superclass 或者 +(Class)superclass返回当前类的父类
//返回当前对象所对应的类
NSString *className =(NSString *) [self class];
NSLog(@"%@类的display方法", className);
//返回当前对象所对应的父类
NSString *superClassName = (NSString *) [self superclass];
NSLog(@"%@类的父类是%@", className, superClassName);
6、-(BOOL)isKindOfClass : (Class)aClass
判断某个实例是否属于某个类或者子类的对象
事例代码如下:
//isKindOfClass的用法
BOOL b = [o2 isKindOfClass:[ObjectTest class]];
if (b == YES) {
NSLog(@"o2是ObjectTest类的对象");
}
7.-(BOOL)isMemberOfClass:(Class)aClass;
只能判断某个实例是否属于某个类,不能判断是否属于某个父类;
//isMemberOfClass
BOOL result = [o2 isMemberOfClass:[NSObject class]];
if (result == NO) {
NSLog(@"isMemberOfClass不能判断是否为NSObject子类的对象");
}
8.-(NSString *) description;
返回字符串形式对象的描述,方便调试
//description
NSString *descript = [o2 description];
NSLog(@"%@", descript);
输出结果: <ObjectTest: 0x100206650>
9.-(NSUInteger) hash;
返回对象的哈希值;
//hash的用法
NSUInteger hash = [o2 hash];
NSLog(@"%p", hash);
输出结果:2014-07-30 11:40:35.685 HelloOC[1130:303] 0x100107b70
10.-(BOOL) isEqual:(id)object; 比较两个对象是否相同,默认是使用地址进行比较的,且hash值一定要相同
//isEqual的用法
NSString *str1 = @"111";
NSString *str2 = str1;
if ([str2 isEqual:str1] == YES)
{
NSLog(@"str2 == str1");
}
else
{
NSLog(@"str2 != str1");
}
Objective-C中的继承
继承是is-a的关系,比如猫咪是一个动物,那么动物是父类,而猫咪是动物的子类。子类具有父类的属性和 行为,以及自身的属性和行为,也就是说“父类更一般,子类更具体
”。