默染江山——oc继承、分类

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

一 引子

继承和分类在不改变原来类模型的前提下,都可以给类扩充一些方法,但是这种两方法有什么区别吗?

二 继承

1.继承的使用场合
1> 当两个类拥有相同属性和方法的时候,就可以将相同的东西抽取到一个父类中
2> 当A类完全拥有B类中的部分属性和方法时,可以考虑让B类继承A类

2.继承的好处:
1> 抽取重复代码
2> 建立了类之间的关系
3> 子类可以拥有父类中的所有成员变量和方法

3.继承的缺点:
耦合性强

4.注意点
1> 基本上所有类的根类是NSObject

5.延伸
1>重写:子类重新实现父类中的某个方法,覆盖父类以前的做法
2>注意
父类必须声明在子类的前面
子类不能拥有和父类相同的成员变量
调用某个方法时,优先去当前类中找,如果找不到,去父类中找

6.实例说明

// Bird的声明
@interface Bird : NSObject
{
    @public
    int weight;
}
- (void)eat;
@end
// Bird的定义
@implementation Bird
- (void)eat {
    NSLog(@"吃吃吃-体重:%d", weight);
}
@end
// Dog的声明
@interface Dog : NSObject
{
    @public
    int weight;
}
- (void)eat;
@end
// Dog的定义
@implementation Dog
- (void)eat {
    NSLog(@"吃吃吃-体重:%d", weight);
}
@end
有相同的属性和行为,抽出一个父类Animal(先抽取weight属性,再抽取eat方法)
// Animal的声明
@interface Animal : NSObject
{
    @public
        int weight;
}
- (void)eat;
@end
// Animal的定义
@implementation Animal
- (void)eat {
    NSLog(@"吃吃吃-体重:%d", weight);
}
@end
子类在父类的基础上拓充属性和方法
// Bird的声明
@interface Bird : Animal
{
    @public
        int height;
}
- (void)fly;
@end

// Bird的定义
@implementation Bird
- (void)fly {
    NSLog(@"飞飞飞-高度:%d", height);
}
@end

// Dog的声明
@interface Dog : Animal
{
    @public
        int speed;
}
- (void)run;
@end
// Dog的定义
@implementation Dog
- (void)run {
    NSLog(@"跑跑跑-高度:%d", speed);
}
@end

三 分类

1.分类的作用
在不改变原来类内容的基础上,可以为类增加一些方法。

2.分类的使用注意
1>分类只能增加方法,不能增加成员变量
2>分类方法实现中可以访问原来类中声明的成员变量
3>分类可以重新实现原来类中的方法,但是会覆盖掉原来的方法,会导致原来的方法没法再使用
4>方法调用的优先级:分类(最后参与编译的分类优先) –> 原来类 –> 父类

3.分类的举例
Person.h

#import <Foundation/Foundation.h>
@interface Person : NSObject
{
    int _age;
}
@property int age;
- (void)test;// 声明test方法
@end

Person.m

#import "Person.h"
@implementation Person
- (void)test // 实现test方法
{
    NSLog(@"Person-test");
}
@end

Person+JJ.h

#import "Person.h"
@interface Person (JJ) // (JJ)表示Person的一个分类
- (void)test2; //在分类中新声明一个test2方法
@end

Person+JJ.m

#import "Person+JJ.h"
@implementation Person (JJ)
- (void)test2 // 在分类中实现新声明的test2方法
{
    NSLog(@"-----test2");
}
- (void)test
{
    NSLog(@"Person (JJ)-test");
}
@end

main.m

#import <Foundation/Foundation.h>
#import "Person.h"
#import "Person+JJ.h"
int main()
{
    Person *p = [[Person alloc] init];
    //p.age = 10;
    // 优先去分类中查找,然后再去原来类中找,最后再去父类中找
    [p test2];
    return 0;
}

上例中,为Person类新建了一个分类Person+JJ,并在分类中添加了一个新的方法test2。

四 总结

继承和分类都可以为类添加一些方法,但是两者还是有很多不同的:
1虽然category可以访问类的实例变量,去不能创建新的实例变量,如果要创新的实例变量,请使用继承。
2 在category中,不提倡对原有方法进行重载。原因非常简单,在category中进行重载,无法对原方法进行访问,而继承中可以使用super。如果真的需要对原方法进行重载,请考虑继承。
3 一个类可以定义多个category,但是如果不同category中存在相同方法,编译器无法决定使用哪个category。
4 在定义category时,我们可以仅仅给出方法定义,而不需要给出具体的实现。这在程序增量开发时是非常有帮助的。
5 category是可以被继承的。在某个父类中定义了category,那么他所有的子类都具有该category。
6 当某个类非常大的时候,Category可以按不同的功能将类的实现分在不同的模块中实现;继承则是都可以完成上面的工作,但是继承有很大的代价问题,一是通过继承来进行扩展是一种耦合很高的行为,对父类可以说是完全依赖;二是继承由于 对父类依赖,所以开发代价相对大,要求对父类的工作流程相对熟悉;三是继承体系如果太复杂会导致整个系统混乱,难以维护。
7 如果你既想提供一系列接口的定义,同时又想提供一些但是又不能提供全部的实现的 时候,这种情况就要使用继承了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值