您的位置:首页 > 其它

2015.7.1 第三堂 init与继承

2015-07-01 22:47 381 查看
概念变复杂,对之前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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: