《黑马程序员》 OC的三大特性(Objective - c语法)

OC 的三大特性:封装、继承、多态。

封装:过滤不合理的值

#import <Foundation/Foundation.h>
// set 方法
// 作用:提供一个方法给外界设置成员变量,可以在方法对成员变量进行赋值和过滤

// get 方法
// 作用:返回对象内部的成员变量,得到成员变量的值。
@interface Student : NSObject
{
    // 成员变量名的命名规范
    // 成员变量名肯定以下划线开头
    // 好处:可以区分参数名称和成员变量的名称,也可以区分变量名和成员变量的名称。
    // @public 在这里不允许写@public,成员变量不允许外部随意修改
    int _age;
}

// set方法的命名规范
// 一定是对象方法,必须以减号-开头
// 返回值类型一定是void
// 必须以set开头,且set后面跟上的成员变量名,变量名的第一个字母必须大写。
// 肯定会有参数,参数类型肯定和成员变量类型一样,形参的名称不能和成员变量名一样。
- (void)setAge:(int)age;

// get方法的命名规范
// 返回值类型肯定和成员变量名一致。
// 方法名和成员变量名一样,
// 不需要接收任何参数。
- (int)age;
@end

@implementation Student

// set方法可以对成员变量进行赋值。
- (void)setAge:(int)age
{
    _age = age;
}
// get方法可以得到成员变量的值
- (int)age;
{
    return _age;
}
@end
int main(int argc, const char * argv[])
{
    Student *stu = [Student new];
    
    [stu setAge:10];
    
    int a = [stu age];
    NSLog(@"%d",a);
    
    
    return 0;
}

set方法

  ① 作用:提供一个方法给外界设置成员变量,可以在方法对成员变量进行赋值和过滤。

  ② set方法的命名规范
           一定是对象方法,必须以减号-开头

           返回值类型一定是void

           必须以set开头,且set后面跟上的成员变量名,变量名的第一个字母必须大写。

           肯定会有参数,参数类型肯定和成员变量类型一样,形参的名称不能和成员变量名一样。

           例:- (void)setAge:(int)age;

  ③ 成员变量的命名规则

           成员变量名肯定以下划线开头

           好处:可以区分参数名称和成员变量的名称,也可以区分变量名和成员变量的名称。

           @public 在这里不允许写@public,成员变量不允许外部随意修改

          例: int _age;

继承

 概念:当两个类中间有相同的属性和行为是就抽取一个类作为父类,让另一个类继承父类:

#import <Foundation/Foundation.h>

// 继承:当两个类中拥有相同的属性和行为时就抽取一个类作为父类,让另一个继承这类父类

@interface Person : NSObject
{
    // 两个成员变量
    int _age;
    double _weight;
}
// age的set和get方法
- (void)setAge:(int)age;
- (int)age;

// weight的set和get方法
- (void)setWeight:(double)weight;
- (double)weight;
@end

@implementation Person

// age的set和get方法的实现
- (void)setAge:(int)age
{
    _age = age;
}
- (int)age
{
    return _age;
}

// weight的set和get方法的实现
- (void)setWeight:(double)weight
{
    _weight = weight;
}
- (double)weight
{
    return _weight;
}
@end

@interface Student : Person

@end

@implementation Student

@end

int main(int argc, const char * argv[])
{

    // 当子类继承父类时,就会拥有父类的所有属性和方法
    Student *stu = [Student new];
    [stu setAge:10];
    int s = [stu age];
    NSLog(@"学生的年龄为%d",s);
    return 0;
}

   注:当子类继承父类就会拥有父类所有的属性和方法。

重写

 重写定义: 在子类里面重新定义和实现类相同的方法和实现

                在对象调用方法过程中首先会在自己的类中找有没有这个方法如果没有这个方法就会去父类里面找

@interface Person : NSObject
{
    // 两个成员变量
    int _age;
    double _weight;
}
// age的set和get方法
- (void)setAge:(int)age;
- (int)age;

// weight的set和get方法
- (void)setWeight:(double)weight;
- (double)weight;
@end

@implementation Person

// age的set和get方法的实现
- (void)setAge:(int)age
{
    _age = age;
}
- (int)age
{
    return _age;
}

// weight的set和get方法的实现
- (void)setWeight:(double)weight
{
    _weight = weight;
}
- (double)weight
{
    return _weight;
}
@end

@interface Student : Person
// 重写: 在子类里面重新定义和实现类相同的方法和实现
// age的set和get方法
- (void)setAge:(int)age;
- (int)age;

// weight的set和get方法
- (void)setWeight:(double)weight;
- (double)weight;

@end

@implementation Student
// age的set和get方法的实现
- (void)setAge:(int)age
{
    _age = age;
}
- (int)age
{
    return _age;
}

// weight的set和get方法的实现
- (void)setWeight:(double)weight
{
    _weight = weight;
}
- (double)weight
{
    return _weight;
}

@end

int main(int argc, const char * argv[])
{

    // 当子类继承父类时,就会拥有父类的所有属性和方法
    Student *stu = [Student new];
    [stu setAge:10];
    int s = [stu age];
    NSLog(@"学生的年龄为%d",s);
    return 0;
}

注意点
     1 父类必须声明在子类前面
     2 子类不能定义与父类相同的成员变量
     3 在对象调用方法时,会首先在自己的类中找,如果没有找到就去父类里面找
    坏处 :藕合性太强,父类必须存在,不存在就不可以使用。

使用场合:

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

     ② 当A类完全拥有B类中的部分属性和方法时就可以考率让B继承A。

    继承  :  XX  是  XX

    组合  :  XX  拥有 XX

当不能满足继承的条件时就使用组合。

多态

特点: 父类类型指向子类对象

         必须有继承才会有多态

#import <Foundation/Foundation.h>
// 多态:1 没有继承就没有多态
//      2 父类指针指向子类对象
// 动物对象
@interface Animal : NSObject

- (void)run;
@end

@implementation Animal
- (void)run
{
    NSLog(@"Animal -- 动物跑起来了");
}
@end

// 狗对象继承Animal
@interface Dog : Animal
- (void)run;
@end

@implementation Dog
- (void)run
{
    NSLog(@"Dog -- 狗跑起来了");
}
@end

// Cat 对象继承Animal
@interface Cat : Animal
- (void)run;
- (void)eat;
@end

@implementation Cat
- (void)run
{
    NSLog(@"cat -- cat跑起来了");
}
- (void)eat
{
    NSLog(@"猫在吃东西");
}
@end

// 如果函数、方法中参数使用的是父类类型,就可出传入父类子类对象
void feel(Animal *dd)
{
    [dd run];
    
}
int main(int argc, const char * argv[])
{

   // 多态:父类指针指向子类对象。
    //Animal *a = [Dog new];
    // 会根据对象类型来调用对象方法
    //[a run]; // 调用到Dog的run方法
   
    // 如果函数、方法中使用的是父类类型,就可出传入父类子类对象
    Dog *d = [Dog new];
    feel(d);
  
    Cat *c = [Cat new];
    feel(c);
    
    // 父类类型的指针,指向子类类型的对象
    // 父类类型的变量不能直接调用子类特有的方法
    // 必须强制转化子类特有的类型才能调用子类的方法
    Animal *a1 = [Cat new];
    //[a1 eat];
    Cat *c1 = (Cat *)a1;
    [c1 eat];
    return 0;
}

注意点:① 没有继承就没有多态

           ②  父类指针指向子类对象

           ③  如果函数或着方法中参数类型是父类类型,就可以传入父类和子类对象

局限性: 父类对象不能直接调用子类特有的方法,

            必须强制转换成子类类型才能直接调用子类特有的方法。

posted @ 2015-03-18 00:24  画梦醉红尘  阅读(277)  评论(0编辑  收藏  举报