[Objective-C]第四天

 知识点回顾:

  1. @try...@catch异常处理.

  2. 类方法.

     a. 声明.

     b. 调用.

     c. 特点.

     d. 注意. 在类方法中不能直接访问属性.也不能使用self直接调用其他的对象方法.

             在类方法的内部创建1个对象 访问这个对象的成员.

             在对象方法中可以直接使用类名来调用类方法.

     e. 什么时候

     f. 规范.

   3. NSString

     a. NSString是1个类.

         NSStrng *str = @"jack";

      b. 常用的方法.

         把C字符串转换为OC字符串.        stringWithUTF8String

         拼接的方式拼接字符串.        stringWithFormat

         长度        length

         得到指定下标的字符         characterAtIndex

         相等        isEqualToString

         比较.        compare

   4. 匿名对象.

      a. 匿名对象.

      b. 如何使用匿名对象.

      c. 匿名对象只能使用1次.

      d. 使用场景

    5.属性的封装.

      a. setter 和 getter 的规范

      b. 封装规范.

      c. 只读 只写.

    6.类与类之间的关系.

      组合

         1个类是由其他的多个类组合而成的. 电脑 CPU 主板 显卡.....

      依赖

      关联

         1个类拥有另外1个对象.

         Person iPad

      继承

   7. 突击

 01-Xcode文档的安装

1. 苹果提供了很多很多的框架.框架中有很多类 很多的函数 提供了一些数据类型.

     遇到的问题:

     a. 你如何知道到底有哪些框架

     b. 框架中有哪些类.

     c. 类只又有哪些牛X的方法.    

     d. 如何调用这些类.

     所有的这一切.Xode文档.详细的描述了这些信息.

 2. Xcode文档需要单独的安装.

     1). 在线安装.

     2). 离线安装.

        /Applications/Xcode.app/Contents/Developer/Documentation/DocSets

02-static关键字

  1. C语言中的static

     a. 修饰局部变量.

     b. 修饰全局变量.

     c. 修饰函数.

  2. OC中的static关键字.

     a. static不能修饰属性 也不能修饰方法.

     b. static可以修饰方法中的局部变量.

         如果方法中的局部变量被static修饰,那么这个变量就会被变成静态变量.

         存储在常量区 当方法执行完毕之后 不会回收 下次再执行这个方法的时候 直接使用 而不会再声明了.

  3. 如果方法的返回值是当前类的对象,那么方法的返回值就写instancetype

03-self关键字

  1. 在方法的内部可以定义1个和属性名相同的局部变量.

     这个时候 如果在方法中访问这个同名的变量,访问的是局部变量.

     问题1: 如果这个时候我就是要访问那个同名的属性,怎么办?

     问题2: 在1个对象方法中要调用当前对象的另外1个对象方法怎么办?

  2. self:自己的.

     和Java、C#中的this关键字有1点点像.

     可以在对象方法和类方法中使用.

     self是1个指针. 在对象方法中self指向当前对象. 在类方法中self指向当前类.

  3. self用在对象方法中.

     1). self在对象方法中,指向当前对象.

         当前对象: 谁调用方法谁就是当前对象.

    2). 在对象方法中,self指向当前对象,然后这又有神马用?

        a. 可以使用self显示的访问当前对象的属性.

            self->属性.  代表访问的是当前对象的这个属性.

         b. 可以使用self来调用当前对象的其他的对象方法.

    3). 对象方法中使用self的场景.

         a. 必须使用self的场景.

            -> 如果在方法中存在和属性同名的局部变量,

               你如果想要访问同名的局部变量,直接写就可以了.

               你如果想要访问当前对象的同名属性 必须使用self

            -> 在对象方法中,如果要调用当前对象的其他的对象方法 必须使用self.

         b.选用self的场景.

            在方法中不存在和属性同名的局部变量 如果这个时候想要访问当前对象的属性

            用布用self效果都是一样的.都是访问的当前对象的属性.

        属性要求以下划线开头 局部变量不要求以下划线开头 按照这个规范来 实际上是不会重名的.

 4. 把slef用在类方法中.

    1). 类加载. 当类第1次被访问的时候 会将类的代码存储在代码区.

               代码区中用来存储类的空间也有1个地址.

    2). 在类方法中 self也是1个指针.执行当前这个类在代码段中的地址.

        self 在类方法中 就相当于是当前这个类.\

    3). 总结1下取到类在代码段中的地址的方式.

        a. 调试查看对象的isa指针的值.

        b. 在类方法中查看self的值.

        c. 调用对象的对象方法class 就会返回这个对象所属的类在代码段中的地址.

        d. 调用类的类方法class 就会返回这个类在代码段中的地址.

    4). 有神马用?

        可以在类方法中使用self来显示的调用本类的其他的类方法.

        使用建议,如果要在当前类方法中调用本类的其他的类方法 虽然可以直接使用类名 但是建议使用self

 5.  对象方法可以声明多次.但是只会认为有1次.

     对象方法如果有多次声明只能实现1次 否则就会报错.

     对象方法之间是不能重名的.

     类方法之间也是不可以重名的.

     但是,对象方法和类方法是可以重名的.

     通过类名来调用 调用的就是类方法

     通过对象名来调 调用的就是对象方法.

 6. 注意

    1). 在对象方法中, self代表当前对象.

        所以可以通过self访问当前对象的成员.

        在对象方法中 不能使用self调用本类的类方法.

    2). 在类方法中,self代表当前这个类.

        所以,可以通过self调用当前类的其他的类方法.

        在类方法中  不能使用self访问对象的成员.

        不能去直接访问属性和调用对象方法.

04-继承

  1. 遇到的问题.

     多个类具有相同的成员.

     a. 复制 粘贴.

        -> 代码冗余.

        -> 后期的维护不方便.

     b.使用继承.

  2. 继承的目的:

        儿子类想拥有父亲类中的所有的成员.但是不想自己去定义,而是想凭空拥有.

  3. 继承的语法:

        如何让1个类认另外1个类为爹 因为想拥有爹类中的所有的成员

     语法:

     @interface 类名 : 父亲类的名称

     @end  

  4. 继承的效果:

     儿子类一旦从父亲类去继承.那么儿子类中拥有了父亲类中的所有的成员. 不用自己定义.

  5. 几个术语:

     @interface Student : Person

     1). Student类从Person类继承. Studdent类是Person类的子类 Person类是Student的父类.

     2). Student类从Person类派生. Student类是Person类的派生类.Person类是Student类的基类.

     子类一旦从父类继承 就意味着子类拥有了父类的所有的成员 而不用自己去定义.

05-使用继承注意与满足继承的关系

  1. 在新创建类模块的时候 指定父类.

     Xcode就会自动的帮助你完成一系列的事情.

  2. 继承是类在继承.而不是对象在继承.

     子类从父类继承.子类中就拥有了父类中定义的所有的成员. 只是类继承.

     我们创建对象. 对象与对象之间是毫无关系的.

  3. 什么时候应该使用继承?

     如果发现另外1个类中的成员我也想有 那么这个时候就可以使用继承.

     千万不要为了继承而去继承. 不要为了仅仅是得到某个类的成员你就不顾伦理去乱继承.

     满足继承的关系 is a

     凡是满足is a关系的类 就可以拥有继承的关系.

     当A类是1个B类的时候 那么A类就可以从B类继承

     Student is a Person.

     学生  人

     学生  狗 X 

     电风扇  电器

     汽车  交通工具.

     汽车  蛇.

  4. 再次的总结:

     1). 子类从父类继承,就意味着子类拥有了父类的所有的成员 包括属性 方法.

     2). 继承是类在继承.而不是对象在继承.

         子类对象中拥有父类对象中的同样的成员.

     3). 满足继承的关系. is a 只有满足is a关系的类才可以拥有继承关系.

  5. 如果有1个成员不是所有的子类都拥有的.那么这个成员就不应该定义在父类之中.

     因为一旦定义在父类之中.那么所有的子类全都有了.

     父类中只定义所有的子类都拥有的.只要不是所有的子类都拥有的 那么就不应该定义在父类之中.

08-继承的特点

  1. 单根性

     1个类只能有1个父类 不能有多个父类.

  2. 传递性.

     A类从B类继承,B类从C类继承. 那么A类就同时拥有B、C类的成员.

  3. NSObject类.    

     是Foundation框架中的类.在这个类中有1个类方法new

     这个方法是用来创建对象的.方法的返回值是创建的这个对象的指针.

     也就是说,如果要创建类的对象,就必须要调用这个new方法.

     如果我们想要让我们的类具备创建对象的能力,就必须要让我们的类直接的或者间接的从NSObject类继承.

     所以.要求: 我们写的类必须直接的或者间接的要NSObject类继承.

     如果你不继承,我们的类就无法创建对象. 那么我们的类就毫无意义.

     在NSObject类之中 还定义了1个属性. 这个属性叫做isa指针.

     所以,每1个子类对象中都有1个叫做isa的指针.

     NSObject类是OC中所有类的祖宗类. 因为OC中的类全部都是直接的或者间接的从它继承,

09-关于子类和父类同名属性

  1. 子类中不能存在和父类同名的属性.

     因为子类从父类继承,就意味着子类拥有了父类的所有的成员 包括属性和方法.

     也就相当于子类中其实已经定义了.

     如果子类再定义1个同名的属性 很明显就冲突了.

  2. super关键字.

     1). 可以用在类方法对象方法之中.

     2). 在对象方法中可以使用super关键字调用当前对象从父类继承过来的对象方法.

     3). 在类方法中 super关键字可以调用当前类从父类继承过来的类方法.

        a. 类方法也能被子类继承. 父类中的类方法可以使用父类名来调用 也可以使用子类名调用.

         b. 在子类的类方法中 可以使用super关键字调用父类的类方法.

     4). super只能用来调用父类的对象方法或者类方法  不能用来访问属性.

  3. 子类从父类继承.

     1). 相当于子类模板中拥有了父类模板中的所有的成员.

     2). 创建1个子类对象,仍然是根据子类模板来创建对象.

         只不过子类模板中拥有父类模板中的成员.

         所以,子类对象中既有子类的成员也有父类的成员.

     3). super特指这个方法是从父类继承过来的.

         super是指当前类或者对象的这个方法是从父类继承过来的.

Son.h

//
//  Son.h
//

#import "Father.h"

@interface Son : Father
{
    NSString *_father;
}
-(void)setFather:(NSString*)father;
-(NSString*)father;
-(void)ziDuiXiangFangFa;
+(void)ziLeiFangFa;
@end

Son.m 

//
//  Son.m
//

#import "Son.h"

@implementation Son
-(void)setFather:(NSString*)father{
    _father=father;
}
-(NSString*)father{
    return _father;
}
-(void)ziDuiXiangFangFa{
    NSLog(@"我是在运行的子对象方法:");
    NSLog(@"    用self调用继承的父类对象方法:");
    [self fuDuiXiangFangFa];
    NSLog(@"    用super调用继承的父类对象方法:");
    [super fuDuiXiangFangFa];
}
+(void)ziLeiFangFa{
    NSLog(@"我是在运行的子类方法:");
    NSLog(@"    用self调用继承的父类类方法:");
    [self fuLeiFangFa];
    NSLog(@"    用super调用继承的父类类方法:");
    [super fuLeiFangFa];
}
@end

 Father.h

//
//  Father.h
//

#import <Foundation/Foundation.h>

@interface Father : NSObject
{
    NSString *_name;
    int _age;
    float _height;
    float _weight;
}

-(void)setName:(NSString*)name;
-(NSString*)name;
-(void)setAge:(int)age;
-(int)age;
-(void)setHeight:(float)height;
-(float)height;
-(void)setWeight:(float)weight;
-(float)weight;
-(void)fuDuiXiangFangFa;
+(void)fuLeiFangFa;
@end

Father.m 

//
//  Father.m
//

#import "Father.h"

@implementation Father
-(void)setName:(NSString*)name
{
    _name = name;
}
-(NSString*)name
{
    return _name;
}
-(void)setAge:(int)age
{
    _age = age;
}
-(int)age
{
    return _age;
}
-(void)setHeight:(float)height
{
    _height = height;
    
}
-(float)height
{
    return _height;
}
-(void)setWeight:(float)weight
{
    _weight = weight;
}
-(float)weight
{
    return _weight;
}
-(void)fuDuiXiangFangFa{
    NSLog(@"我是运行的父对象方法!");
}
+(void)fuLeiFangFa{
    NSLog(@"我是运行的父类方法!");
}

@end

 main.m

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


int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Son *s1 =[Son new];
        [s1 setName:@"巴巴祖"];
        [s1 setFather:@"巴巴爸爸"];
        NSLog(@"----    [s1 ziDuiXiangFangFa];  -----");
        [s1 ziDuiXiangFangFa];
        NSLog(@"----    [Son ziLeiFangFa];      -----");
        [Son ziLeiFangFa];
        NSLog(@"----    [Father fuLeiFangFa];   -----");
        [Father fuLeiFangFa];
    }
    return 0;
}

10-访问修饰符

 1. 访问修饰符: 用来修饰属性.

     可以限定对象的属性在那1段范围之中访问.

     @private: 私有 被@private修饰的属性只能在本类的内部访问.

               只能在本类的方法实现中访问.

     @protected: 受保护的. 被@protected修饰的属性只能在本类和本类的子类中访问.

                只能在本类和子类的方法实现中访问.

     @package: 被@package修饰的属性 可以在当前框架中访问.

     @public: 公共的.被@public修饰的属性 可以在任意的地方访问.

  2. 如果不为属性指定访问修饰符 那么默认的就是@protected

  3. 子类仍然可以继承父类的私有属性.

     只不过,在子类中无法去直接访问从父类继承过来的私有属性.

     但是如果父类中有1个方法再为属性赋值或者取值.

     那么子类可以调用这个方法间接的访问父类的私有属性.

  4. 访问修饰符的作用域.

     从写访问修饰符的地方开始往下.直到遇到另外1个访问修饰符或者结束大括弧为止。

     中间的所有的属性都应用这个访问修饰符.

  5. 使用建议.

     1). @public 无论什么情况下都不要使用. 属性不要直接暴露给外界.

     2). @private 如果属性只想在本类中使用 不想在子类中使用 那么就使用它.

     3). @protected: 如果你希望属性只在本类和本类的子类中使用.

     推荐使用默认的@protected

  6. 访问修饰符只能用来修饰属性 不能用来修饰方法.

11-私有属性和私有方法

   1. 我们刚才讲的@private修饰的属性就叫做私有属性.

      只能在类的内部访问.

      但是在外界的时候,Xcode仍然会提示这个对象中有这个属性 只不过没权访问.

      我们想要实现的效果:真私有. 让外界不知道对象里面有这么1个属性.

    2. 其实在@implementaion之中也可以写1个大括号.

      把属性定义在@implementation的大括号之中.

      这里面的属性. 是1个私有属性. 各种访问修饰符无效.

      外界根本就不会提示.

      将属性定义在@implementation之中 和 将属性定义在@interface之中并标记为@private

      唯一的区别: 提示和不提示. 都不能在外界访问.

   3. 私有方法.

      方法不写声明,只写实现. 那么这个方法就是1个私有方法.

      只能在本类的其他方法中调用 不能再外界调用.

12-里氏替换原则

  1. 里氏替换原则 --- LSP

     子类可以替换父类的位置.并且程序的功能不受影响.

     为什么?

     1). 父类指针迫切的需求要1个父类对象,而我们给了1个子类对象,

         这是完全没有问题的. 因为子类就是1个父类嘛.

     2). 因为父类中拥有的成员 子类都有. 所以不会影响程序的功能.

  2. 里氏替换原则的表现形式.

     当1个父类指针指向1个子类对象的时候,这里就有里氏替换原则.

  3. LSP的作用。

     1). 1个指针中不仅可以存储本类对象的地址还可以存储子类对象的地址.

     2). 如果1个指针的类型是NSObject类型的,那么这个指针中可以存储任意的OC对象的地址.

     3). 如果1个数组的元素的类型是1个OC指针类型的 那么这个数组中不仅可以存储本类对象还可以存储子类对象.

     4). 如果1个数组的元素是NSObject指针类型 那么意味着任意的OC对象都可以存储到这个数组之中.

     5). 如果1个方法的参数是1个对象,那么我们在为这个参数传值的时候.

         可以传递1个本类对象 也可以传递1个子类对象.

         对方法中的代码不会有丝毫的影响.

  4. 当1个父类指针指向1个子类对象的时候.

     这个时候,通过这个父类指针就只能去调用子类对象中的父类成员.

     子类独有的成员无法访问.

     只需要记住,不要问为什么 时机一到我自然会告诉你!

13-方法重写

  1. 子类从父类继承,子类就继承了父类的方法.

    子类继承了父类的方法,就意味着子类拥有了这个功能.

    有的时候: 虽然子类也拥有父类的这个行为. 但是这个行为的具体的实现和父类不同.

 2. 这个时候怎么办?

     拥有父类的行为,但是行为的具体的实现和父类的实现不一样.

     那么子类就自己按照自己的方式重写这个方法就可以了.

     如何重写: 直接在类的实现中将这个方法重新实现一遍就可以了.

  3. 什么时候子类需要重写父类的方法.

     子类拥有父类的行为,但是子类这个行为的实现和父类不一样.那么就按照自己的方式重写这个方法就可以了.

  4. 当1个父类指针指向1个子类对象的时候.

     通过这个父类指针调用的方法 如果在子类中重写了.

     调用的就是子类重写的方法.

  5. 多态.

     指的是同1个行为,对于不同的事物具有完全不同的表现形式.

     找三个人过来.

     医生

     演员

     理发师

     cut 指令.

     同1个行为 具备多种形态.

14-杀人游戏

  1. 杀手

        方法: 可以杀各种各样的人.

  2. 每1个人被杀的时候,都要叫. 但是每1个人叫的形式是不一样的.

     每1个人都有1个叫的方法.

     Person:

     男人 超级赛亚人 火星人.

15-description

  1. %p 打印的是指针变量的值.

     %@ 打印的是指针指向的对象.

  2. 如果我们使用%@打印1个对象

     输出的格式:  <对象所属的类名:对象的地址>

 3. 原理:

    当我们使用%@打印1个对象的时候, NSLog函数的底层实现.

     1). 调用传入的对象的 description方法.

     2). 拿到这个方法的返回值 这个返回值是1个字符串.

     3). 将这个字符串输出.

 4. description方法是定义在NSObject类之中的.

     所以每1个OC对象都有这个方法.

     这个方法在NSObject类中的实现是这样的:

     返回的字符串格式 @"<对象所属的类名:对象的地址>"

  5. 什么时候需要重写description方法呢?

     如果你希望使用%@打印1个对象的时候 你希望这个对象打印的个数是我们自定义的.

     那么就可以重写这个方法.

作业:

1.设计2个类,类之间的关系自拟(比如继承、组合)

1> 车

(1)属性

* 轮子数

* 速度

//
//  Vehicle.h
//

#import <Foundation/Foundation.h>

@interface Vehicle : NSObject
{
    int _wheelNum;
    int _speed;
}

-(void)setWheelNum:(int)wheelNum;
-(int)wheelNum;
-(void)setSpeed:(int)speed;
-(int)speed;

@end

(2)方法

* 属性相应的set和get方法

//
//  Vehicle.m
//

#import "Vehicle.h"

@implementation Vehicle
-(void)setWheelNum:(int)wheelNum{
    _wheelNum = wheelNum;
}
-(int)wheelNum{
    return _wheelNum;
}
-(void)setSpeed:(int)speed{
    _speed = speed;
}
-(int)speed{
    return _speed;
}
@end

2> 客车

(1)属性

* 轮子数

* 速度

* 座位数

//
//  Car.h
//

#import "Vehicle.h"

@interface Car : Vehicle
{
    int _seats;
}
-(void)setSeats:(int)seats;
-(int)seats;
@end

(2)方法

* 属性相应的set和get方法

//
//  Car.m
//

#import "Car.h"

@implementation Car
-(void)setSeats:(int)seats{
    _seats = seats;
}
-(int)seats{
    return _seats;
}
@end

/*----------------------------------------*/

2.设计2个类,类之间的关系自拟(比如继承、组合)

1> 身材数据

(1)属性

* 身高

* 体重

* 手长

* 脚长

//
//  Body.h
//
#import <Foundation/Foundation.h>

@interface Body : NSObject
{
    float _height;
    float _weight;
    float _handLen;
    float _footLen;
}

-(void)setHeight:(float)height;
-(float)height;
-(void)setWeight:(float)weight;
-(float)weight;
-(void)setHandLen:(float)handLen;
-(float)handLen;
-(void)setFootLen:(float)footLen;
-(float)footLen;
@end

(2)方法

* 属性相应的set和get方法

//
//  Body.m
//

#import "Body.h"

@implementation Body
-(void)setHeight:(float)height{
    _height = height;
}
-(float)height{
    return _height;
}
-(void)setWeight:(float)weight{
    _weight =weight;
}
-(float)weight{
    return _weight;
}
-(void)setHandLen:(float)handLen{
    _handLen = handLen;
}
-(float)handLen{
    return _handLen;
}
-(void)setFootLen:(float)footLen{
    _footLen = footLen;
}
-(float)footLen{
    return _footLen;
}
@end

2> 人

(1)属性

* 年龄

* 身高

* 体重

* 手长

* 脚长

//
//  Person.h
//

#import <Foundation/Foundation.h>
#import "Body.h"
@interface Person : NSObject
{
    int _age;
    Body * _body;
    
}
-(void)setBody:(Body *)body;
-(Body*)body;
-(void)setAge:(int)age;
-(int)age;

@end

(2)方法

* 属性相应的set和get方法

//
//  Person.m
//

#import "Person.h"

@implementation Person
-(void)setBody:(Body *)body{
    _body = body;
}
-(Body*)body{
    return _body;
}
-(void)setAge:(int)age{
    _age = age ;
}

-(int)age{
    return  _age;
}
@end
//
//  main.m
//

#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        Person *p1 =[Person new];
        [p1 setAge:20];
        Body * body = [Body new];
        [body setHeight:170.1];
        [body setWeight:51.5];
        [body setHandLen:75];
        [body setFootLen:100];
        
        [p1 setBody:body];
        NSLog(@"年龄:%d 身高:%.1lf 体重:%.1lf 手长:%.1lf 脚长:%.1lf",
              [p1 age],
              [[p1 body] height],
              [[p1 body] weight],
              [[p1 body] handLen],
              [[p1 body] footLen]
              );
    }
    return 0;
}

/*----------------------------------------*/

3.设计3个类,类之间的关系自拟(比如继承、组合)

1> 人

(1)属性

* 姓名

* 年龄

//
//  Person.h
//

#import <Foundation/Foundation.h>

@interface Person : NSObject
{
    NSString *_name ;
    int _age;
}
-(void)setName:(NSString*)name;
-(NSString*)name;
-(void)setAge:(int)age;
-(int)age;
-(void)setName:(NSString*)name andAge:(int)age;
@end

(2)方法

* 属性相应的set和get方法

* 设计一个对象方法同时设置姓名和年龄

//
//  Person.m
//

#import "Person.h"

@implementation Person
-(void)setName:(NSString*)name{
    _name = name;
}
-(NSString*)name{
    return _name;
}
-(void)setAge:(int)age{
    _age = age;
}
-(int)age{
    return _age;
}
-(void)setName:(NSString*)name andAge:(int)age{
    _name = name;
    _age =age;
}
@end

2> 书

(1)属性

* 书名

* 出版社名称

* 作者(包含姓名和年龄)

//
//  Book.h
//

#import <Foundation/Foundation.h>
#import "Person.h"
@interface Book : NSObject
{
    NSString *_bookname;
    NSString *_publisher;
    Person *_author;
}
-(void)setBookname:(NSString*)bookname;
-(NSString*)bookname;
-(void)setPublisher:(NSString*)publisher;
-(NSString*)publisher;
-(void)setAuthor:(Person*)author;
-(Person*)author;
@end

(2)方法

* 属性相应的set和get方法

//
//  Book.m
//

#import "Book.h"

@implementation Book
-(void)setBookname:(NSString*)bookname{
    _bookname = bookname;
}
-(NSString*)bookname{
    return _bookname;
}
-(void)setPublisher:(NSString*)publisher{
    _publisher = publisher;
}
-(NSString*)publisher{
    return _publisher;
}
-(void)setAuthor:(Person*)author{
    _author =author;
}
-(Person*)author{
    return _author;
}
@end

3> 学生

* 姓名

* 年龄

* 学号

* 书(随身带着一本书)

//
//  Student.h
//

#import "Person.h"
#import "Book.h"
@interface Student : Person
{
    int _id;
    Book * _book;
}
-(void)setId:(int)id;
-(int)id;
-(void)setBook:(Book *)book;
-(Book *)book;
-(void)study;
@end

2> 方法

* 属性相应的set和get方法

* 设计一个对象方法-study:输出书名

//
//  Student.m
//

#import "Student.h"

@implementation Student
-(void)setId:(int)id{
    _id = id ;
}
-(int)id{
    return _id;
}
-(void)setBook:(Book *)book{
    _book = book;
}
-(Book *)book{
    return _book;
}
-(void)study{
    NSLog(@"随身书籍名称:%@",[_book bookname]);
}
@end
//
//  main.m
//

#import <Foundation/Foundation.h>
#import "Student.h"
#import "Book.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Student *s1 = [Student new];
        [s1 setName:@"王大锤"];
        [s1 setAge:20];
        [s1 setId:54321];
        Book * b1 =[Book new];
        [b1 setBookname:@"临高启明"];
        [s1 setBook:b1];
        [s1 study];
    }
    return 0;
}

/*----------------------------------------*/

4.设计Car类

1> 属性

* 速度

2> 方法

* 属性相应的set和get方法

* 一个对象方法跟其他车子比较车速,返回速度差

* 一个类方法比较两辆车的车速,返回速度差

//
//  Car.h
//

#import <Foundation/Foundation.h>

@interface Car : NSObject
{
    float _speed;
}
-(void)setSpeed:(int)speed;
-(int)speed;
-(double)speedDifferenceWith:(float)speed;
+(double)speedDifferenceWith:(float)speeda and:(float)speedb;

@end
//
//  Car.m
//

#import "Car.h"

@implementation Car
-(void)setSpeed:(int)speed{
    _speed = speed;
}
-(int)speed{
    return _speed;
}
-(double)speedDifferenceWith:(float)speed{
    return (_speed-speed);
}
+(double)speedDifferenceWith:(float)speeda and:(float)speedb{
    return speeda - speedb ;
}
@end
//
//  main.m
//

#import <Foundation/Foundation.h>
#import "Car.h"
int main(int argc, const char * argv[]) {

    Car * c1 = [Car new];
    
    [c1 setSpeed:300];
    
    NSLog(@"c1 与 时速180 的速度差为 %.1lf KM/H",
          [c1 speedDifferenceWith:180]);
    NSLog(@"时速200 与 时速180 两车速度差为:%.1lf  KM/H",
         [Car speedDifferenceWith:200 and:180]);
    
    
    return 0;
}

/*----------------------------------------*/

5.设计一个类Point2D,用来表示二维平面中某个点

1> 属性

* double x

* double y

//
//  Point2D.h
//

#import <Foundation/Foundation.h>

@interface Point2D : NSObject
{
    double _x;
    double _y;
}
-(void)setX:(double)x;
-(double)x;
-(void)setY:(double)y;
-(double)y;
-(void)setX:(double)x andY:(double)y;

-(double)distanceWithOtherPoint:(Point2D*)otherPoint;

+(double)distanceWithPointA:(Point2D*)p1 andPonintB:(Point2D*)p2;

@end

2> 方法

* 属性相应的set和get方法

* 设计一个对象方法同时设置x和y

* 设计一个对象方法计算跟其他点的距离

* 设计一个类方法计算两个点之间的距离

//
//  Point2D.m
//

#import "Point2D.h"

@implementation Point2D
-(void)setX:(double)x{
    _x = x;
}
-(double)x{
    return _x;
}
-(void)setY:(double)y{
    _y = y;
}
-(double)y{
    return _y;
}
-(void)setX:(double)x andY:(double)y{
    _x = x;
    _y = y;
}
-(double)distanceWithOtherPoint:(Point2D*)otherPoint
{
    double res1 = pow((_x - otherPoint->_x),2);
    double res2 = pow((_y-otherPoint->_y),2);
    return sqrt(res1+res2);
    
}
+(double)distanceWithPointA:(Point2D*)p1 andPonintB:(Point2D*)p2
{
    double res1 = pow((p1->_x - p2->_x),2);
    double res2 = pow((p1->_y-p2->_y),2);
    return sqrt(res1+res2);
}
@end

3> 提示

* C语言的math.h中有个函数:double pow(double n, double m); 计算n的m次方

* C语言的math.h中有个函数:double sqrt(double n); 计算根号n的值(对n进行开根)

/*----------------------------------------*/

6.设计一个类Circle,用来表示二维平面中的圆

1> 属性

* double _radius (半径)

* Point2D *_point (圆心)

//
//  Circle.h
//

#import <Foundation/Foundation.h>
#import "Point2D.h"
@interface Circle : NSObject
{
    double _radius;
    Point2D *_point;
}
-(void)setRadius:(double)radius;
-(double)radius;
-(void)setPoint:(Point2D*)point;
-(Point2D*)point;
-(BOOL)isOverlapWith:(Circle*)circle;
+(BOOL)isOverlapWithCircleA:(Circle *)circleA andCircleB:(Circle*)circleB;
@end

2> 方法

* 属性相应的set和get方法

* 设计一个对象方法判断跟其他圆是否重叠(重叠返回YES,否则返回NO)

* 设计一个类方法判断两个圆是否重叠(重叠返回YES,否则返回NO)

判断两个圆是否重叠的公式: 两圆心的距离之和小于两圆半径之和

//
//  Circle.m
//

#import "Circle.h"

@implementation Circle
-(void)setRadius:(double)radius{
    _radius = radius;
}
-(double)radius{
    return _radius;
}
-(void)setPoint:(Point2D*)point{
    _point = point;
}
-(Point2D*)point{
    return _point;
}
-(BOOL)isOverlapWith:(Circle*)circle{
    double res = [_point distanceWithOtherPoint:[circle point]];
    return (res - (_radius + [circle radius])< 0? YES : NO );
}
+(BOOL)isOverlapWithCircleA:(Circle *)circleA andCircleB:(Circle*)circleB{
    
    double res = [Point2D distanceWithPointA:[circleA point] andPonintB:[circleB point]];
    return (res - ([circleA radius]+[circleB radius])<0 ?YES : NO);
}
@end
//
//  main.m
//

#import <Foundation/Foundation.h>
#import "Circle.h"
int main(int argc, const char * argv[]) {

    Circle *c1 = [Circle new];
    Circle *c2 = [Circle new];
    
    [c1 setRadius:15.56];
    [c2 setRadius:25.73];
    
    Point2D *p1 = [Point2D new];
    Point2D *p2 = [Point2D new];
    
    [p1 setX:100 andY:200];
    [p2 setX:105 andY:205];
    
    [c1 setPoint:p1];
    [c2 setPoint:p2];
    
    
    NSString *chr = ([Circle isOverlapWithCircleA:c1 andCircleB:c2] == YES ? @"YES" : @"NO" );
    
    NSLog(@"c1 与 c2 是否重叠:%@",chr);
    
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值