2.面向对象之继承

第一部分 基础知识


1.什么是继承

如果类B继承了类A 则B中拥有A的所有东西,类A称为B的父类,类B称为A的子类。表达方法:@interface 类B:类A。


2.继承的使用场合

1)当两个类拥有相同属性和方法的时候,就可以将相同的东西抽取到一个父类中;
2)当A类中完全拥有B类中得部分属性和方法时,可以考虑让B继承A类: 如果“B”是 “A”读着符合人们的思维(例如dog是Animal)使用继承;如果“B”属于“A”读着符合人们的 思维(例如Score   属于 Student)则使用组合。

3.继承特性

1)抽取重复代码,精简代码量;

        2)建立了类之间的关系;

        3)子类中拥有了父类的所有东西。

4)耦合性太强,容易产生错误。当父类中属性产生需错误的时候则继承他的所有子类都产生错误。


4.重写

子类中心实现父类中的某个方法,覆盖父类以前的做法。

注意:1.父类必须声明在子类的前面;

2.OC不允许子类和父类拥有相同名称的成员变量(java可以);

3.子类中和父类中存在相同的方法时,优先调用子类中方法。如果子类中不存在时则从父类中找。

5.super(关键字)

1.作用:

  1)直接调用父类中的某个方法;

  2)super处在对象方法中,那么就会调用父类的对象方法; super处在类方法中,那么就会调用父类的类方法。

2.使用场合:子类重写父类的方法时想保留父类的一些行为。


第二部分 代码示例

1.继承代码示例

建立一个Person类和一个Student类,并且Student类继承Person类。
#import <Foundation/Foundation.h>

@interface Person :NSObject

// 对象方法
- (void)eat;
- (void)sleep;
- (void)walk;

// 类方法
+ (void)walk;

@end

@implementation Person

// 对象方法eat的实现
- (void)eat
{
    NSLog(@"eat eat eat !");
}

// 对象方法sleep的实现
- (void)sleep
{
    NSLog(@"sleep~");
}

// 类方法walk的实现
+ (void)walk
{
    NSLog(@"调用了+walk");
}

// 对象方法walk的实现
- (void)walk
{
    NSLog(@"调用了-walk");
}

@end


// Student类继承自Person
@interface Student :Person

+ (void)does;
- (void)does;

// 重写父类中得walk方法
- (void)walk;
@end

@implementation Student

- (void)walk
{
    NSLog(@"调用了walk");
}
+ (void)does
{
    // 调用父类中得walk方法
    [super walk];
    NSLog(@"do + some thing");
}
- (void)does
{
    // self关键字:调用Student类中得walk方法
    [self walk];
    NSLog(@"do - some thing");
}
@end

1. main函数中直接调用Student的does方法:

int main( )
{
    [Student does];
    return 0;
}

运行结果:

2015-05-07 20:47:38.328 继承的使用[3538:303] 调用了+walk
2015-05-07 20:47:38.330 继承的使用[3538:303] do + some thing
Program ended with exit code: 0
当调用Student类的does时,直接运行了 + ( void)does 这个方法,并且在这个方法中调用了父类中得 - ( void)walk 方法。

2.当由子类对象调用does时:

int main( )
{ 
    Student *s = [Student new];
    [s does];
    return 0;
}
运行结果
2015-05-07 21:00:13.182 继承的使用[3620:303] 调用了walk
2015-05-07 21:00:13.184 继承的使用[3620:303] do - some thing
Program ended with exit code: 0

当由对象调用does的时候,由于子类中重写了父类的walk方法,所以输出的是调用了walk;而不是: 调用了-walk。

3. 当由子类对象调用的eat时:

int main( )
{
      Student *s = [Student new];
      [s eat];
      return 0;
}

运行结果:

2015-05-07 21:07:00.513 继承的使用[3665:303] eat eat eat !
Program ended with exit code: 0
Student对象继承了Person对象,也就拥有了Person的属性,并且子类中也没有重写eat,所以直接调用了父类中得eat方法

2.组合代码分析

// 定义Score类
@interface Score : NSObject
{
    int _cScore;
    int _ocScore;
}
@end

@implementation Score
@end

// 定义Student类
@interface Student : NSObject
{
    // 组合
    Score *_score;
    // int _age;
}
-	(void)setScore:(Score *)score;
-	(Score *)score;
@end

@implementation Student
-	(void)setScore:(Score *)score
{
	_score = score;
}
-	(Score *)score
{
	return _score;
}

@end
相比于Student是Score而言,说Score属于Student更符合人们的思维,所以在此使用组合而不是继承,即在Student类中定义一个Score属性。
但是在定义一个Student类的时候还需要定义个Score类,并且使Student类指向Score类。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值