oc学习笔记(四)面向对象-类的三大特性:封装,继承,多态

一、封装

成员变量的封装,或方法的封装

第一部分.get ,set方法

1.set方法

 作用:提供一个方法给外界设置成员变量值,

可以在方法里面对参数进行相应过滤

命名规范:

 1> 方法名必须以set开头

 2> set后面跟上成员变量的名称,成员变量的首字母必须大写

 3> 返回值一定是void

 4> 一定要接收一个参数,而且参数类型跟成员变量类型一致

 5> 形参的名称不能跟成员变量名一样

2.

/*
 get方法
 1.作用:返回对象内部的成员变量
 2.命名规范:
 1> 肯定有返回值,返回值类型肯定与成员变量类型一致
 2> 方法名跟成员变量名一样
 3> 不需要接收任何参数
 */

3.如果只读的话,就可以只提供get方法,不提供set方法

#import 

@interface Student : NSObject
{
    // 成员变量尽量不要用@public
    // @public
    int age;
    
    //@public
    // 只读(readonly):只允许外界访问我的no,不允许外界修改我的no
    int no; // 只需要提供get方法
}

//
/*
 set方法
 1.作用: 提供一个方法给外界设置成员变量值,可以在方法里面对参数进行相应过滤
 2.命名规范:
 1> 方法名必须以set开头
 2> set后面跟上成员变量的名称,成员变量的首字母必须大写
 3> 返回值一定是void
 4> 一定要接收一个参数,而且参数类型跟成员变量类型一致
 5> 形参的名称不能跟成员变量名一样
 */
- (void)setAge:(int)newAge;

/*
 get方法
 1.作用:返回对象内部的成员变量
 2.命名规范:
 1> 肯定有返回值,返回值类型肯定与成员变量类型一致
 2> 方法名跟成员变量名一样
 3> 不需要接收任何参数
 */
- (int)age;

- (void)study;

@end

@implementation Student

// set方法的实现
- (void)setAge:(int)newAge
{
    // 对传进来的参数进行过滤
    if (newAge <= 0)
    {
        newAge = 1;
    }
    
    age = newAge;
}

- (int)age
{
    return age;
}

- (void)study
{
    NSLog(@"%d岁的学生在学习", age);
}

@end

int main()
{
    Student *stu = [Student new];
    //stu->age = -10;
    
    //stu->age = 10;
    
    [stu setAge:10];
    
    
    NSLog(@"学生的年龄是%d岁", [stu age]);
    
    //[stu study];
    
    
    return 0;
}

4.成员变量的命名规范:

@interface Student : NSObject

{/*成员变量的命名规范:一定要以下划线 _开头

  作用:

  1.让成员变量和get方法的名称区分开

  2.可以跟局部变量区分开,一看到下划线开头的变量,一般都是成员变量

  */

    int _no;

    Sex _sex;

}

@end

@implementation Student


- (void)setSex:(Sex)sex

{

    _sex = sex;

}


5.封装的一个好处,在set方法的时候就进行计算,

每次改动的时候就进行计算,进行一些操作。

- (void)setCScore:(int)cScore

{

    _cScore = cScore;

    

    // 计算总分

    _totalScore = _cScore + _ocScore;

    _averageScoe = _totalScore/2;

}

6.oc经典错误

消息机制

#import 

// 尽管编译器容错能力比较,但是写代码必须规范
@interface Person : NSObject
- (void)test;
@end

@implementation Person
- (void)test
{
    NSLog(@"哈哈哈");
}
@end

// 一旦运行过程中出错,就会闪退

/*
 -[Person test]: unrecognized selector sent to instance 0x7fd2ea4097c0
 给Person对象发送了一个不能识别的消息:test
 */

int main()
{
    Person *p = [Person new];
    // OC是在运行过程中才会检测对象有没有实现相应的方法
    [p test];
    return 0;
}


不能识别 消息 发送 给对象

oc学习笔记(四)面向对象-类的三大特性:封装,继承,多态_第1张图片

7.只有方法声明,没有方法实现,

就会出现闪退


二、继承

/*

 1.继承的好处:

 1> 抽取重复代码

 2> 建立了类之间的关系

 3> 子类可以拥有父类中的所有成员变量和方法

 

.注意点

 1> 基本上所有类的根类是NSObject

 */


另一个根类是NSProxy


继承父类

子类中不允许子和父类有相同名黎的成员变量


2.子类重新实现父类中的某个方法,称为重写

覆盖父类以前的做法。

1》.父类必须声明在子类的前面


3.每个类里面都有个指针 ,superclass

oc学习笔记(四)面向对象-类的三大特性:封装,继承,多态_第2张图片

4.每个对象继承NSObjct 里的isa,

oc学习笔记(四)面向对象-类的三大特性:封装,继承,多态_第3张图片


4.调用某个方法时,优先去当前类中找,如果找不到,就往上级父类找。

5.继承的坏处

耦合性太强。

6,继承的使用场合

 1> 当两个类拥有相同属性和方法的时候,就可以将相同的东西抽取到一个父类中

 2> A类完全拥有B类中的部分属性和方法时,可以考虑让B类继承A


7.组合

//继承:xx 是xxx

//xx 拥有 xxx

@interface Score : NSObject
{
    int _cScore;
    int _ocScore;
}
@end

@implementation Score
@end

@interface Student : NSObject
{
    // 组合
    Score *_score;
//    int _cScore;
//    int _ocScore;
    int _age;
}
@end

@implementation Student

@end


8.super用法
/*
 僵尸
 
 跳跃僵尸、舞王僵尸、铁桶僵尸
 */
#import 

/*
 super的作用
 1.直接调用父类中的某个方法
 2.super处在对象方法中,那么就会调用父类的对象方法
   super处在类方法中,那么就会调用父类的类方法
 
 3.使用场合:子类重写父类的方法时想保留父类的一些行为
 */

// 僵尸
@interface Zoombie : NSObject
- (void)walk;

+ (void)test;
- (void)test;

@end

@implementation Zoombie
- (void)walk
{
    NSLog(@"往前挪两步******");
}

+ (void)test
{
    NSLog(@"Zoombie+test");
}

- (void)test
{
    NSLog(@"Zoombie-test");
}
@end

// 跳跃僵尸
@interface JumpZoombie : Zoombie
+ (void)haha;
- (void)haha2;
@end


@implementation JumpZoombie

+ (void)haha
{
    [super test];
}

- (void)haha2
{
    [super test];
}

- (void)walk
{
    // 跳两下
    NSLog(@"跳两下");
    
    // 走两下(直接调用父类的walk方法)
    [super walk];
    //NSLog(@"往前挪两步----");

}
@end

int main()
{
    //[JumpZoombie haha];
    JumpZoombie *jz = [JumpZoombie new];
    
    [jz haha2];
    
    return 0;
}




三、多态

    // 多种形态

    //Dog *d = [Dog new]; // Dog类型

    

    // 多态:父类指针指向子类对象

    Animal *a = [Dog new];

    

    // 调用方法时会检测对象的真实类型

会动态绑定

    [a eat];


#import 

/*
 多态
 1.没有继承就没有多态
 2.代码的体现:父类类型的指针指向子类对象
 3.好处:如果函数\方法参数中使用的是父类类型,可以传入父类、子类对象
 4.局限性:
 1> 父类类型的变量 不能 直接调用子类特有的方法。必须强转为子类类型变量后,才能直接调用子类特有的方法
 */

// 动物
@interface Animal : NSObject
- (void)eat;
@end

@implementation Animal
- (void)eat
{
    NSLog(@"Animal-吃东西----");
}
@end

// 狗
@interface Dog : Animal
- (void)run;
@end

@implementation  Dog
- (void)run
{
    NSLog(@"Dog---跑起来");
}
- (void)eat
{
    NSLog(@"Dog-吃东西----");
}
@end

// 猫
@interface Cat : Animal

@end

@implementation Cat
- (void)eat
{
    NSLog(@"Cat-吃东西----");
}
@end

// 这个函数是专门用来喂动画
//void feed(Dog *d)
//{
//    [d eat];
//}
//
//void feed2(Cat *c)
//{
//    [c eat];
//}
//

// 如果参数中使用的是父类类型,可以传入父类、子类对象
void feed(Animal *a)
{
    [a eat];
}

int main()
{
    // NSString *d = [Cat new];
    // [d eat];
    
    /*
    Animal *aa = [Dog new];
    // 多态的局限性:父类类型的变量 不能 用来调用子类的方法
    //[aa run];
    
    // 将aa转为Dog *类型的变量
    Dog *dd = (Dog *)aa;
    
    [dd run];
    */
    
    //Dog *d = [Dog new];
    
    //[d run];
    
    /*
    Animal *aa = [Animal new];
    feed(aa);
    
    Dog *dd = [Dog new];
    feed(dd);
    
    Cat *cc = [Cat new];
    feed(cc);
     */
    
    /*
    // NSString *s = [Cat new];
    Animal *c = [Cat new];
    
    
    NSObject *n = [Dog new];
    NSObject *n2 = [Animal new];
    
    
    // 多种形态
    //Dog *d = [Dog new]; // Dog类型
    
    // 多态:父类指针指向子类对象
    Animal *a = [Dog new];
    
    // 调用方法时会检测对象的真实形象
    [a eat];
    */
    return 0;
}

2.多态的好处。

喂不同动物,一起写,利用父类,传不同类型,节省代码

// 这个函数是专门用来喂动画

//void feed(Dog *d)

//{

//    [d eat];

//}

//

//void feed2(Cat *c)

//{

//    [c eat];

//}

//


// 如果参数中使用的是父类类型,可以传入父类、子类对象

void feed(Animal *a)

{

    [a eat];

}


    Animal *aa = [Animal new];

    feed(aa);

    

    Dog *dd = [Dog new];

    feed(dd);

    

    Cat *cc = [Cat new];

    feed(cc);

3.局限性

虽然父类类型的变量,可以调用子类方法成功(编译有警告)

但是父类类型的变量 不能用来调用子类方法。

如果非要调用,必须强转

    /*

    Animal *aa = [Dog new];

    // 多态的局限性:父类类型的变量不能用来调用子类的方法

    //[aa run];

    

    // aa转为Dog *类型的变量

    Dog *dd = (Dog *)aa;

    

    [dd run];

    */




你可能感兴趣的:(object-c基础)