黑马程序员——ObjC基础—对象的其他要点

来源:互联网 发布:c程序员面试宝典 pdf 编辑:程序博客网 时间:2024/05/20 00:11
-----------Java培训、Android培训、IOS培训、.Net培训、期待与您交流!------------ 
在前面的学习中有一些零星的要点,总结在这里。

1、匿名对象
    [NSObject new];
上面的代码定义了一个匿名的对象,也就是说,没有指针指向这个对象,这种对象只有在创建的时候能进行操作,之后则无法调用,一般不建议使用,只做简单的了解。

2、数据监听
我们举一个常见的统计分数的例子,我们要求创建一个分数对象,包含数学、语文、英语分数等属性,以及总分和平均分属性,总分和平均分显然是通过各门课程的分数直接求出来的,不应该另行设置,我们看看该如何实现:
@interface Score : NSObject// 注意这里的nonatomic不能省略,因为我们打破了自动线程管理的规范@property (nonatomic) int mathScore;@property (nonatomic) int chineseScore;@property (nonatomic) int englishScore;@property  (nonatomic) int totalScore;@property (nonatomic) int averageScore;@end@implementation Score// set方法重写(取代自动生成的set方法)- (void)setMathScore:(int)mathScore{    _mathScore = mathScore;    _totalScore = _mathScore + _chineseScore + _englishScore; // 监听    _averageScore = _totalScore / 3; // 监听}- (void)setChineseScore:(int)chineseScore{    _chineseScore = chineseScore;    _totalScore = _mathScore + _chineseScore + _englishScore; // 监听    _averageScore = _totalScore / 3; // 监听}- (void)setEnglishScore:(int)englishScore{    _englishScore = englishScore;    _totalScore = _mathScore + _chineseScore + _englishScore; // 监听    _averageScore = _totalScore / 3; // 监听}@endint main(){        Score *s = [Score new]; // 创建新分数对象    s.mathScore = 80; // 赋值(每赋值一次,总分和均分都会计算一次)    s.chineseScore = 90; // 赋值(每赋值一次,总分和均分都会计算一次)    s.englishScore = 95; // 赋值(每赋值一次,总分和均分都会计算一次)        NSLog(@"totalScore is %d", s.totalScore); // 总分直接输出    NSLog(@"averageScore is %d", s.averageScore); // 平均分直接输出    return 0;}
这种在参数设置的过程中,添加的代码,实际上实现了监听参数变化的效果,类似这样的处理,我们称之为监听。

3、对象里的对象
我们知道,一个对象内部可以有多个属性,属性可不可以是对象呢?这当然也是可以的,注意,当属性为对象的时候,实际上这个属性是一个指向另一个对象的指针。(其实,前面用到的NSString类型的字符串就是一个对象),我们来看下面的例子:
// Dog 类@interface Dog : NSObject@property NSString *name;@end@implementation Dog@end// Person 类@interface Person : NSObject@property NSString *name;@property Dog *dog; // 狗作为人的一个参数@end@implementation Person@endint main(){        Dog *d = [Dog new]; //创建狗对象    d.name = @"Wowo";        Person *p = [Person new]; // 创建人对象    p.name = @"xiaoming";    p.dog = d; // 人对象获取狗对象        // 输出(注意d的属性是通过p取得的)    NSLog(@"I am %@, I have a dog named %@!", p.name, p.dog.name);        return 0;}

4、组合
当两个类之间没有什么逻辑关系,但是又有相同的属性时,我们一般是采用组合的方式来设计,相同的部分,我们提取为一个类,然后在另一个类里,把这个类当成一个属性。这和上面的例子的实现基本一致。
// Score 类@interface Score : NSObject@property int chineseScore;@property int englishScore;@property int mathScore;@end@implementation Score@end// Student 类@interface Student : NSObject@property NSString *name;@property int number;@property Score *score; // 分数类作为学生的一个属性(组合)@end@implementation Student@end
这样一来,学生对象就有了分数对象里面的属性。只不过操作的时候,要多一个点语法操作。

5、self和super
self在OC中是一个特殊的指针,用于表示当前的对象,而super是一个编译器特定,他指向当前类的父类。
// Animal 类(父类)@interface Animal : NSObject@property int age;- (void)showDetail;@end@implementation Animal- (void)showDetail{    NSLog(@"Age is %d", self.age); // 通过self操作属性}@end// Dog 类(子类)@interface Dog : Animal@property NSString *name;@end@implementation Dog- (void)showDetail{ // 重写父类中存在的方法    NSLog(@"Name is %@", self.name); // 通过self操作属性    [super showDetail]; // 通过super访问父类方法}@end// 主函数int main(){        Dog *d = [Dog new];    d.name = @"Wowo";    d.age = 3;    [d showDetail]; // 该show方法将会同时调用父类的show方法        return 0;}
输出如下:
2015-02-13 13:19:05.447 Study[21944:303] Name is Wowo2015-02-13 13:19:05.450 Study[21944:303] Age is 3

6、重写
在上面的例子中已经出现了方法的重写,这种在父类中存在的方法,如果我们不希望子类继承,可以在子类中重写方法,只要和父类中的方法名称参数都一样即可,注意,不需要重新声明方法。在某个继承链中,当每一级别的类里都有某个方法时,方法的调用是从当前对象开始往上追溯的,遇到的第一个为执行的方法。

7、多态
定义对象时,类型指定为父类及以上的情况,可实现对象的多态。我们通过一个简单的例子来理解这个概念:
定义一个人的类,有一个喂食的方法,可以喂狗和猫东西吃。在实际操作中,我们可以抽象出动物的概念,猫和狗都继承自动物,我们只要能给动物喂食,相应的也能给猫和狗喂食,猫和狗的类中也可以重写出个性化的处理,不会出现干扰。
我们来看看怎么实现:
// Animal 类@interface Animal : NSObject- (void)eat;@end@implementation Animal- (void)eat{ // eat 方法    NSLog(@"Animal eat!");}@end// Dog 类 --> Animal 类@interface Dog : Animal@end@implementation Dog- (void)eat{ // 重写    NSLog(@"Dog eats!");}@end// Cat 类 --> Animal 类@interface Cat : Animal@end@implementation Cat- (void)eat{ // 重写    NSLog(@"Cat eats!");}@end// Person 类@interface Person : NSObject- (void)feedAnimal:(Animal*)animal;@end@implementation Person- (void)feedAnimal:(Animal*)animal{    NSLog(@"Feed a %@", animal); // 输出的是具体对象    [animal eat]; // 先在具体对象内找方法}@end// 主函数int main(){        Person *p = [Person new];    Cat *c = [Cat new];    Dog *d = [Dog new];        [p feedAnimal:c]; // 可以对多种对象进行操作    [p feedAnimal:d]; // 可以对多种对象进行操作        return 0;}
通过上面的代码,我们可以发现,定义的方法可以接收多种对象,而且每个对象能够做出不一样的处理,来看看输出结果:
2015-02-13 18:05:11.226 Study[22236:303] Feed a <Cat: 0x1002026d0>2015-02-13 18:05:11.229 Study[22236:303] Cat eats!2015-02-13 18:05:11.230 Study[22236:303] Feed a <Dog: 0x100202850>2015-02-13 18:05:11.231 Study[22236:303] Dog eats!







-----------Java培训、Android培训、IOS培训、.Net培训、期待与您交流!------------ 


0 0
原创粉丝点击