zoukankan      html  css  js  c++  java
  • Objective-C基础之面向对象的定义、类和对象

    1、类的定义:

    在Xcode中添加文件,选择Cocoa Class 或者Cocoa Touch Class

    cocoaClass

    输入类名Person,并选择父类为NSObject

    ClassName默认生成如下两个文件

    Person.h

    //
    //  Person.h
    //  ClassAndObject
    //
    //  Created by Kenshin Cui on 14-2-1.
    //  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    
    @end
    

    Person.m

    //
    //  Person.m
    //  ClassAndObject
    //
    //  Created by Kenshin Cui on 14-2-1.
    //  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
    //
    
    #import "Person.h"
    
    @implementation Person
    
    @end

    在ObjC中定义一个类需要两个文件.h和.m:

    .h文件:放类的声明,包括成员变量、属性和方法声明(事实上.h文件不参与编译过程);关键字@interface声明一个类,同时它必须以@end结束,在这两个关键字中间声明相关成员;在声明Person类的同时可以看到它继承于NSObject,这是ObjC的基类,所有的类最终都继承于这个类(但是需要注意ObjC中的基类或者根类并不只有一个,例如NSProxy也是ObjC的基类),由于这个类在Foundation框架中定义,所以导入了<Foundation/Foundaton.h>(这么描述的意思是导入Foundation框架中的Foundation.h声明文件); 

    .m文件:放属性、方法的具体实现;关键字@implementation用于实现某个类,同时必须以@end结尾,在这两个关键字中间实现具体的属性、方法;由于.m中使用了Person类,所以需要导入声明文件“Person.h”;

    2、成员变量

    假设在Person类中包含人员姓名(name)、年龄(age)、民族(nation)、身高(height)四个成员变量,同时姓名和年龄两个成员变量是私有的,身高是公开的,民族则限制为只有子类可以访问。

    //
    //  Person.h
    //  ClassAndObject
    //
    //  Created by Kenshin Cui on 14-2-1.
    //  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>//由于使用了NSObject,所以导入此头文件
    
    //NSObject是基类,Person实现了NSObject
    @interface Person : NSObject{
        /*成员变量必须包含在大括号中
         *注意成员变量不声明任何关键字的话是默认可访问性@Protected
         *注意在ObjC中不管是自定义的类还是系统类对象都必须是一个指针,例如下面的_name
         */
        @private
        NSString *_name;//在ObjC中推荐成员变量名以_开头
        int _age;
        @protected
        NSString *_nation;
        @public
        float height;
    }
    
    @end
    

    成员变量定义在.h文件中,同时必须定义在类后面的{}内。成员的可访问性通过下面三个关键字声明:

    • @private 私有成员,只有当前类可以访问; 
    • @protected 受保护成员,只有当前类或子类可以访问(如果没有添加任何修饰则默认为@protected); 
    • @public 公共成员,所有类均可访问;

    在ObjC中可访问性修饰符除了这三种,还有一个@package不太常用,它类似于C#中的internal在框架内是公共的,但是框架外是私有的(也就是只能在一个框架内可以访问)。那么既然身高是公共的,外界怎么访问呢?

    //
    //  main.m
    //  ClassAndObject
    //
    //  Created by Kenshin Cui on 14-2-1.
    //  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    #import "Person.h"
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            Person *p=[Person alloc];
            p=[p init];
            //上面两句代码可以直接写成:Person *p=[[Person alloc] init];
            //还可以写成:Person *p=[Person new];
            
            p->height=1.72;
            NSLog(@"height=%.2f",p->height);//结果:height=1.72
        }
        return 0;
    }
    

    这里需要注意几点:

    ObjC中所有的对象类型的变量都必须加上“*”,在ObjC中对象其实就是一个指针(例如之前看到的NSString也是如此,但是基本类型不用加”*”); 

    ObjC中使用[]进行方法调用,在ObjC中方法调用的本质就是给这个对象或类发送一个消息; 

    在ObjC中类的实例化需要两个步骤:分配内存、初始化; 

    类的初始化调用了父类的init方法,如果使用默认初始化方法进行初始化(没有参数),内存分配和初始化可以简写成[Person new]; 

    公共成员的调用使用“->”操作符;

    2.1 成员变量和属性的区别;

    总结: 

    • 成员变量用于类内部,无需与外界接触的变量。
    • 根据成员变量的私有性,为了方便访问,所以就有了属性变量。属性变量的好处就是允许让其他对象访问到该变量。当然,你可以设置只读或者可写等,设置方法也可自定义。所以,属性变量是用于与其他对象交互的变量。

    一些建议:
    1.如果只是单纯的private变量,最好声明在implementation里.
    2.如果是类的public属性,就用property写在.h文件里
    3.如果自己内部需要setter和getter来实现一些东西,就在.m文件的类目里用property来声明 

    .h中的interface的大括号{}之间的实例变量,.m中可以直接使用;

    .h中的property变量,.m中需要使用self.propertyVariable的方式使用propertyVariable变量

    下面这个程序,aboutList,和 otherList 到底有什么不同,

    @interface OtherMain : UIViewController
    

    {

        NSMutableArray *aboutList;

    }
    @property (nonatomic,retain)NSMutableArray *otherList;
    aboutList是私有成员变量,其它类是访问不到这个私有成员变量的。
    otherList是属性,是整个工程所有类都可见,其它类是可以访问得到这个成员变量的。
    “但是什么时候用aboutList的写法的,什么时候用otherList的写法!!!”
    本类(UIViewController)要使用的话就用aboutList或self. otherList,其它类要使用的话就用otherList。

     一、类Class中的属性property

      在ios第一版中,我们为输出口同时声明了属性和底层实例变量,那时,属性是oc语言的一个新的机制,并且要求你必须声明与之对应的实例变量,例如:

    @interface MyViewController :UIViewController
    {
        UIButton *myButton;
    }
    @property (nonatomic, retain) UIButton *myButton;
    @end

      最近,苹果将默认编译器从GCC转换为LLVM(low level virtual machine),从此不再需要为属性声明实例变量了。如果LLVM发现一个没有匹配实例变量的属性,它将自动创建一个以下划线开头的实例变量。因此,在这个版本中,我们不再为输出口声明实例变量。

      例如:MyViewController.h文件

    @interface MyViewController :UIViewController
    @property (nonatomic, retain) UIButton *myButton;
    @end

      在MyViewController.m文件中,编译器也会自动的生成一个实例变量_myButton。那么在.m文件中可以直接的使用_myButton实例变量,也可以通过属性self.myButton.都是一样的。

      注意这里的self.myButton其实是调用的myButton属性的getter/setter方法。

      例如在oc中有如下代码

      .h文件

    @interface MyViewController :UIViewController
    {
        NSString *name;
    }
    @end

      .m文件中,self.name 这样的表达式是错误的。xcode会提示你使用->,改成self->name就可以了。因为oc中点表达式是表示调用方法,而上面的代码中没有name这个方法。

      oc语法关于点表达式的说明:如果点表达式出现在等号 = 左边,该属性名称的setter方法将被调用。如果点表达式出现在右边,该属性名称的getter方法将被调用。"

      所以在oc中点表达式其实就是调用对象的setter和getter方法的一种快捷方式, 例如:dealie.blah = greeble 完全等价于 [dealie.blah setBlah:greeble];

       以前的用法,声明属性跟与之对应的实例变量:

    @interface MyViewController :UIViewControlle
    {
        UIButton *myButton;
    }
    @property (nonatomic, retain) UIButton *myButton;
    @end

      这种方法基本上使用最多,现在大部分也是在使用,因为很多开源的代码都是这种方式。但是ios5更新之后,苹果是建议以以下的方式来使用:

    @interface MyViewController :UIViewController
    @property (nonatomic, retain) UIButton *myButton;
    @end

      因为编译器会自动为你生成以下划线开头的实例变量_myButton,不需要自己手动再去写实例变量。而且也不需要在.m文件中写@synthesize myButton;也会自动为你生成setter,getter方法。@synthesize的作用就是让编译器为你自动生成setter与getter方法。

      @synthesize 还有一个作用,可以指定与属性对应的实例变量,例如@synthesize myButton = xxx;那么self.myButton其实是操作的实例变量xxx,而不是_myButton了。

      在实际的项目中,我们一般这么写.m文件

    @synthesize myButton;

      这样写了之后,那么编译器会自动生成myButton的实例变量,以及相应的getter和setter方法。注意:_myButton这个实例变量是不存在的,因为自动生成的实例变量为myButton而不是_myButton,所以现在@synthesize的作用就相当于指定实例变量;

      如果.m文件中写了@synthesize myButton;那么生成的实例变量就是myButton;如果没写@synthesize myButton;那么生成的实例变量就是_myButton。所以跟以前的用法还是有点细微的区别。

     二、类别中的属性property (不明白,待解决)

      类与类别中添加的属性要区分开来,因为类别中只能添加方法,不能添加实例变量。经常会在ios的代码中看到在类别中添加属性,这种情况下,是不会自动生成实例变量的。比如在:UINavigationController.h文件中会对UIViewController类进行扩展

    @interface UIViewController (UINavigationControllerItem)
    @property(nonatomic,readonly,retain) UINavigationItem *navigationItem;
    @property(nonatomic) BOOL hidesBottomBarWhenPushed;
    @property(nonatomic,readonly,retain) UINavigationController *navigationController;
    @end

      这里添加的属性,不会自动生成实例变量,这里添加的属性其实是添加的getter与setter方法。

      注意一点,匿名类别(匿名扩展)是可以添加实例变量的,非匿名类别是不能添加实例变量的,只能添加方法,或者属性(其实也是方法)。

     

     

  • 相关阅读:
    118/119. Pascal's Triangle/II
    160. Intersection of Two Linked Lists
    168. Excel Sheet Column Title
    167. Two Sum II
    172. Factorial Trailing Zeroes
    169. Majority Element
    189. Rotate Array
    202. Happy Number
    204. Count Primes
    MVC之Model元数据
  • 原文地址:https://www.cnblogs.com/wangliyuan/p/4729660.html
Copyright © 2011-2022 走看看