黑马程序员-iOS学习日记(七)面向对象-核心语法(二)

---------------------- <a href="http://www.itheima.com"target="blank">iOS开发</a>、<a href="http://www.itheima.com"target="blank">iOS培训</a>、期待与您交流! ----------------------


一、分类

1、作用:在不改变原来类内容的基础上,可以为类增加一些方法

2、示例代码:

// Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
{
    NSString *_name;
}
@property NSString *name;
- (void)walk;
@end

// Person.m
#import <Foundation/Foundation.h>
#import "Person.h"
@implementation Person
- (void)walk
{
    NSLog(@"Person的walk方法");
}
@end

// Person+WR.h
#import <Foundation/Foundation.h>
#import "Person.h"
@interface Person (WR)
- (void)walk;
- (void)eat;
@end

// Person+WR.m
#import <Foundation/Foundation.h>
#import "Person+WR.h"
@implementation Person (WR)
- (void)walk
{
    NSLog(@"PersonWR的walk方法");
}
- (void)eat
{
    NSLog(@"PersonWR的eat方法");
}
@end

#import <Foundation/Foundation.h>
#import "Person.h"
#import "Person+WR.h"
int main()
{
    Person *p =[[Person alloc] init];
    [p walk];
    // PersonWR的walk方法
    [p eat];
    // PersonWR的eat方法
    return 0;
}


</pre><pre>
3、使用注意

a、分类只能增加方法,不能增加成员变量(会造成成员变量的重复声明)b、分类方法实现中可以访问原来类中声明的成员变量(分类就是原来类的一部分)

c、分类可以重新实现原来类中的方法,但是会覆盖掉原来的方法,会导致原来的方法没法再使用(类似继承,子类覆盖父类的方法)

d、方法调用的优先级:分类(最后参与编译的分类优先) --> 原来类  --> 父类

二、类的本质

1、类也是一个对象,是Class类型的对象,简称“类对象”,类名就代表着类对象,每个类只有一个类对象。

2、Class类型的定义

typedef struct objc_class *Class;

3、获得类对象的方式

// 第一种方式 通过类名获得
Class c = [Person class];
    
// 第二种方式 通过类的对象获得
Person *p = [[person alloc] init];
Class c = [p class];

4、调用类方法的方式

// 第一种方式 通过类名调用类方法
Person *p = [Person new];
    
// 第二种方式 通过类对象名调用类方法
Class c = [Person class];
Person *p = [c new];

5、+load和+initialize

a、+load

在程序启动的时候会加载所有的类和分类,并调用所有类和分类的+load方法

先加载父类,再加载子类;也就是先调用父类的+load,再调用子类的+load

先加载元原始类,再加载分类

不管程序运行过程有没有用到这个类,都会调用+load加载

b、+initialize

在第一次使用某个类时(比如创建对象等),就会调用一次+initialize方法

一个类只会调用一次+initialize方法,先调用父类的,再调用子类的

#import <Foundation/Foundation.h>

@interface Person : NSObject
@end

@implementation Person
+ (void)load
{
    NSLog(@"Person-load");
}
+ (void)initialize
{
    NSLog(@"Person-initialize");
}
@end

@interface Student : Person
@end

@implementation Student
+ (void)load
{
    NSLog(@"Student-load");
}
+ (void)initialize
{
    NSLog(@"Student-initialize");
}
@end

@interface Student (WR)
@end

@implementation Student (WR)
+ (void)load
{
    NSLog(@"Student(WR)-load");
}
+ (void)initialize
{
    NSLog(@"Student(WR)-initialize");
}
@end


int main()
{
    // Person-load
    // Student-load
    // Student(WR)-load
    
    Student *s = [[Student alloc] init];
    // Person-initialize
    // Student(WR)-initialize
    
    return 0;
}

三、description方法

1、类中存在两个description方法,分别为类方法description和对象方法description;

2、类方法description使用NSLog(@"%@", 类名);会打印输出:类名

      对象方法description使用NSLog(@"%@", 类名);会打印输出:<类名:内存地址>


四、SEL

1、SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去找对应的方法地址。找到方法地址就可以调用方法

a、把test2包装成SEL类型的数据

b、把test2包装成SEL类型的数据

c、根据方法地址调用对应的方法

2、示例代码

Person *p = [[Person alloc] init];
    
// 间接调用有参数的构造方法
[p performSelector:@selector(setName:) withObject:@"WhyRanR"];  // 注意 setName后面要加:
    
// 间接调用无参的构造方法
NSString *name = [p performSelector:@selector(name)];
    
// 获得SEL类型对象
SEL s1 = @selector(test);                   // 方法 -> SEL对象
SEL s2 = NSSelectorFromString(@"test");     // 方法名字符串 -> SEL对象
NSString *str = NSStringFromSelector(s);    // SEL对象 -> 方法名字符串
3、得到指向当前方法的SEL对象

_cmd

---------------------- <a href="http://www.itheima.com"target="blank">iOS开发</a>、<a href="http://www.itheima.com"target="blank">iOS培训</a>、期待与您交流! ----------------------

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值