2015.7.1 第三堂 init与继承

概念变复杂,对之前property理解不够透彻加电脑网速卡导致效率较低。

小结:加强对概念的理解


知识点一:property的理解

首先,属性和方法不能混为一谈。


先按旧模式理解:

属性需要先在.h文件中 1、@interface里声明成员变量2、为该成员变量定义set和get方法

再到.m文件中 3、分别实现这两个方法 终于得到了“属性”

最后回到main.m中调用方法

再按照新模式理解:

引入@property,只需要在.h文件中写一行 @property生成属性变量即可完成以上三个功能,有了属性


*property 是对"成员变量拥有属性"三个步骤的简化,由此生成的变量这叫做属性变量 (即属性变量拥有setget方法和声明,而成员变量只是最初括号里的声明)

*只有属性才用到property(单词意即属性),方法仍需要定义和实现,与之是不同的。

*之前用@property完成声明set get,用@synthesize完成实现set get,现在这俩功能合并为一个@property了


之前东哥的@property代码部分:


//
//  Person.h
//  Review
//
//  Created by PengXiaodong on 15/6/30.
//  Copyright (c) 2015年 PengXiaodong. All rights reserved.
//

#import <Foundation/Foundation.h>

/*
 旧的变量声明的方式存在一个弊端
 1. 繁琐 每一个变量都需要提供一个set方法 get方法 同时需要去实现这个两个方法
 
 解决上面的问题
 property-声明了变量的set get方法
 synthesize-实现了set get方法
 */
@interface Person : NSObject{
    //声明变量
    int age;//成员变量
}

//定义方法
//set方法 设置变量的值
- (void)setAge:(int)aAge;

//get方法 后去变量的值
- (int)age;

@end


//  Person.m
//  Review
//
//  Created by PengXiaodong on 15/6/30.
//  Copyright (c) 2015年 PengXiaodong. All rights reserved.
//

#import "Person.h"

@implementation Person

- (void)setAge:(int)aAge{
    age = aAge;
}

- (int)age{
    return age;
}
@end

//

//  Cat.h
//  Review
//
//  Created by PengXiaodong on 15/6/30.
//  Copyright (c) 2015年 PengXiaodong. All rights reserved.
//

#import <Foundation/Foundation.h>
/*
 旧的变量声明的方式存在一个弊端
 1. 繁琐 每一个变量都需要提供一个set方法 get方法 同时需要去实现这个两个方法
 
 解决上面的问题
 property-声明了变量的set get方法
 synthesize-实现了set get方法
 */

/*
 @property属性变量
1. 声明了setter方法
2. 声明了getter方法
3. 声明了一个变量 这个变量本身的名字是 _name
- (void)setName:(NSString *)name;
- (NSString *)name;
 */

/*
 关键字
 nonatomic:非原子操作 线程不安全(没有加锁 解锁机制) 效率高
 atomic:原子操作 线程安全(有加锁 解锁机制) 默认     效率低
 
 ->OC对象类型 strong/retain
 strong:声明强引用 引用计数+1 retainCount
 weak: 弱引用  不引用
 retain:strong同样的功能
 copy:复制一个同样的对象(创建一片内存,将对象的内容拷贝到这片独立的内存)
 
 readWrite:默认-可读(有getter方法)可写(有setter方法)
 readOnly:只能读(只有getter方法 没有setter方法)
 
 setter:  使用方式setter=setCatname:
 getter:  使用方式getter=getCatName
 
 assign:  C语言的基本数据类型
 */
@interface Cat : NSObject

@property (nonatomic, strong) NSString *name;
//- (void)setName:(NSString *)name;
//- (NSString *)name;

@property (nonatomic, strong) NSString *address;
//- (void)setAddress:(NSString *)address;
//- (NSString *)address;

@property (nonatomic, assign) float age;

@end

//
//  Cat.m
//  Review
//
//  Created by PengXiaodong on 15/6/30.
//  Copyright (c) 2015年 PengXiaodong. All rights reserved.
//

#import "Cat.h"

@implementation Cat
//@synthesize name = _name;//完成了set方法 get方法的实现

@end


知识点二:self与super
self:表示1.当前的这个类或者2.当前这个类的一个对象,也就是说:self代表着当前方法的调用者。

super:表示父类的一个对象,等同于NSObject

观察以下代码:

- (instancetype)initWithName:(NSString *)name{

    if (self = [super init]){

        self.name = name;

        [self setName:name];

    }

    return self;

}

1、instancetype 代表任何实例类型,是oc的对象类型(和id一样,更常用)

void *(泛型)是空指针类型,可以指向任意一个类型的指针

2、 if (self = [super init])是合并了判断和初始化的代码


不一定对的理解:

如 self = [super init];

self:通过super(表示父类的一个对象)调用init方法初始化这个对象,所以此时self是这个类的一个对象

而super(父类是NSObject,所以是NSObject的一个对象,粗略理解这里写super和NSObject效果一致)。

不过为啥不写一个 对象名 而写了一个类名呢。。。。。???

是初始化super这个类成一个对象(怎么可能,又不是实例化),还是初始化super这个类的对象 赋给self?


需要记住的:构造函数 (创建对象本身的同时 马上给他一些初始值)

- (instancetype)initWithName:(NSString *)name{

    if (self = [super init]){  

        self.name = name;

       // [self setName:name];

    }

    return self;

}

关于我为什么说“ if (self = [super init])是合并了判断和初始化的代码”,解释如下,两段代码等同:

- (instancetype)initWithName:(NSString *)name ide:(int)identifier{    //告诉父类初始化一下自己

    self = [super init];             //初始化一个对象给self

    if (self != nil){                   // 判断是否初始化成功(oc中的nil 等同于 c语言中的NULL 表示“空" )

        self.name = name;   //初始化成功

        self.idNum = identifier;

    }

    return self;            //返回值有两种情况 1. 成功-对象本身  2. 失败-返回空nil

}

@end   

知识点三:是类还是对象 1 2

具体情况具体分析。


知识点四:父类和子类

再创建文件的时候,写父类的文件名,即创建了子类。 这之间的联系,是继承。

在子类中,可以重写/添加父类的方法和属性。


关于继承的优缺点:

优点:可以复用别的类的一些方法或者属性

缺点:必须要自己重新创建一个新的类,有些方法和属性子类是不需要的但一旦继承了就摆脱不了。(之后可避免)

什么时候用继承:给一个类添加方法或者属性的时候

 注意:1、OC里面只有单继承,不能继承多个父类。

(如:在Children.h中写

#import "Father.h"

#import "Person.h" 即错误的写法)

2、所以如果要实现多继承,目前只能一个一个地去继承。(如person-father-children)




参考资料:

为什么很多人同时写属性和成员变量http://segmentfault.com/q/1010000000185056

IOS OC声明变量在@interface括号中与使用@property的区别http://blog.csdn.net/shenjie12345678/article/details/39052659

对象创建,self,super的详解http://www.2cto.com/kf/201402/276749.html

关于 self 和 super 在oc中的疑惑 与分析http://www.cnblogs.com/tangbinblog/p/4034890.html


附件:全部代码
//
//  main.m
//  Review
//
//  Created by BaoCloud-iMac1 on 15/7/1.
//  Copyright (c) 2015年 BaoCloud-iMac1. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Person.h"

#import "Father.h"
#import "Children.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        /*
        Person *pxd = [[Person alloc] init];
        [pxd setName:@"xiaowang"];
        pxd.name = @"xiaowang";
        
        Person *zhangsan = [Person new];
        [zhangsan setName:@"zhangsan"];
        zhangsan.name = @"zhangsan";
        */
        
        Father *fth = [[Father alloc] init];
        fth.name = @"Peng";
       // [fth setName:@"ee"];
        fth.age = 49;
        [fth work];
        
        Children *ch = [[Children alloc] init];
        ch.name = @"PXD";
        ch.age = 28;
        [ch work];
    }
    return 0;
}


//
//  Person.h
//  Review
//
//  Created by BaoCloud-iMac1 on 15/7/1.
//  Copyright (c) 2015年 BaoCloud-iMac1. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Person : NSObject
/*
 atomic: 原子操作 加锁解锁 效率比较低
 nonatmic:
 
 当修饰OC对象类型的时候使用strong
 strong:强引用 retainCount + 1
 retain:
 weak: 不引用,只是为了和strong配对
 
 readonly:告诉编译器只为我们申明一个getter方法 不需要setter
 readWrite:可读getter 可写setter
 
 setter=
 getter=
 */
@property (nonatomic, strong) NSString *name;
- (void)showMyName;
- (instancetype)initWithName:(NSString *)name;

+ (void)doSomething;
- (void)test;
@end

//
//  Person.m
//  Review
//
//  Created by BaoCloud-iMac1 on 15/7/1.
//  Copyright (c) 2015年 BaoCloud-iMac1. All rights reserved.
//

#import "Person.h"

@implementation Person

/*property作用
 1.setter
 2.getter
 3._name
 */

/*
 self
 1. 表示当前这个类
 2.表示当前这个类的一个对象
 
 */
- (void)showMyName{
    NSLog(@"%@", _name);//访问变量本身
    NSLog(@"%@", self.name);//访问变量的get方法
    NSLog(@"%@", [self name]);
}

/*
 void * (泛型)空指针类型 可以指向任意一个类型的指针变量
 instancetype 实例类型 Person* Cat* Car*
 id   OC的对象类型
 */


/*
 super 表示父类的一个对象 继承 cocos2d-X LUA
 */
- (instancetype)initWithName:(NSString *)name{
    if (self = [super init]){
        self.name = name;
        [self setName:name];
    }
    return self;
}

+ (void)doSomething{
    //Person *pxd = [[self alloc] initWithName:@"android"];
}

- (void)test{
    [Person doSomething];
}
@end



//
//  Car.h
//  Review
//
//  Created by BaoCloud-iMac1 on 15/7/1.
//  Copyright (c) 2015年 BaoCloud-iMac1. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Car : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) int  idNum;

//构造函数 (创建对象本身的同时 马上给他一些初始值)
//名字 age ID
//init方法 alloc] init]
- (Car *)initWithName:(NSString *)name ide:(int)identifier;


@end

//
//  Car.m
//  Review
//
//  Created by BaoCloud-iMac1 on 15/7/1.
//  Copyright (c) 2015年 BaoCloud-iMac1. All rights reserved.
//

#import "Car.h"

@implementation Car

/*
- (instancetype)initWithName:(NSString *)name ide:(int)identifier{
    //告诉父类初始化一下自己
    //1. 成功-对象本身
    //2. 失败-返回空nil
    self = [super init];
    
    //判断是否初始化成功
    //断了个腿  少了个胳膊  没有鼻子
    if (self != nil){
        //初始化成功
        self.name = name;
        //[self setName:name];
        _idNum = identifier;
    }
    
    //返回值有两种情况
    //1. 成功-对象本身
    //2. 失败-返回空nil
    return self;
}
 */


/*
- (instancetype)initWithName:(NSString *)name ide:(int)identifier{
    if (self = [super init]) {
        self.name = name;
        self.idNum = identifier;
    }
    return self;
}
 比下面那个专业 推荐这个
*/

- (instancetype)initWithName:(NSString *)name ide:(int)identifier{
    self = [super init];
    
    //C-null
    //OC-nil
    if (self != nil){
        self.name = name;
        self.idNum = identifier;
    }
    return self;
}
@end

//
//  Father.h
//  Review
//
//  Created by BaoCloud-iMac1 on 15/7/1.
//  Copyright (c) 2015年 BaoCloud-iMac1. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Father : NSObject{
    @private//私有成员变量  这个变量只能在当前这个类里面用 在子类和外部都无法使用
    NSString *money;
    @protected//受保护的成员变量  这个变量可以在当前这个类 和子类里面使用  不能再外部访问。
    NSString *house;
    @public
    NSString *sigarette;
}

@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) int  age;

- (void)work;

@end
//关于成员变量和属性变量的区别:成员变量在括号里面声明的还需要实现啥的 属性变量是property的还提供了setget方法

//
//  Father.m
//  Review
//
//  Created by BaoCloud-iMac1 on 15/7/1.
//  Copyright (c) 2015年 BaoCloud-iMac1. All rights reserved.
//

#import "Father.h"

@implementation Father

- (void)work{
    NSLog(@"打工仔");
}
@end

//
//  Children.h
//  Review
//
//  Created by BaoCloud-iMac1 on 15/7/1.
//  Copyright (c) 2015年 BaoCloud-iMac1. All rights reserved.
//

#import "Father.h"
#import "Person.h"
/*
 优点:可以复用别的类的一些方法或者属性
 缺点:必须要自己重新创建一个新的类, 
      有些方法和属性子类是不需要的 但是一旦继承了 就摆脱不了了。
 
 什么时候用继承:给一个类添加方法或者属性的时候
 
 OC里面只有单继承 不能继承多个父类
 如果要实现多继承 目前只能一个一个地去继承
 */
@interface Children : Father

@property (nonatomic, strong) NSString *dipan;
- (void)show;

@end


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值