OC(一)类、对象、属性、成员变量、方法(整理)

来源:互联网 发布:知乎日报和读读日报 编辑:程序博客网 时间:2024/06/05 12:53
第一节   类、对象

>类(Class):具有相同属性和行为等同一类元素等总称,类是一个抽象的概念。
在Java中,类就是同一类事物的统称,例如:鸟类、人类、鱼类等等。
在OC中,类是表示对象类型的结构体,对象通过类来获取自身的各种信息,包括各种实例方法或类方法。

>对象/实例(Instance):事物存在的实体,是不可细分的,代表着某一个具体的东西。
在Java中,对象是事物存在的实体。通常将对象划分为两个部分:静态部分【属性】与动态部分【行为】。
在OC中,对象是一种包含值和只想其类的隐藏指针的结构体。可通过类实例化变为对象(alloc,new,copy,工厂方法,单例方法)等。

>类与对象的关系:类实质上就是封装对象属性和行为的载体,而对象则是类抽象出来的一个实例。类是对世间事物的抽象称呼,而对象则是这个事物对应的实体。

类——实例化一个——>对象

类的构成

>导入接口
#import “ItsSuperclass.h"
接口文件通常包含在#import 指令中 
#import与#include 的区别:作用一样,唯一的区别是这条指令可以确保同一个文件不会被导入多次。
@class 与#import的区别:
1、#import方式会包含被引用类的所有信息,包括被引用类的变量和方法;@class方式只是告诉编译器在A.h文件中 B *b 只是类的声明,具体这个类里有什么信息,这里不需要知道,等实现文件中真正要用到时,才会真正去查看B类中信息;
2、使用@class方式由于只需要只要被引用类(B类)的名称就可以了,而在实现类由于要用到被引用类中的实体变量和方法,所以需要使用#importl来包含被引用类的头文件;
3、通过上面2点也很容易知道在编译效率上,如果有上百个头文件都#import了同一 个文件,或者这些文件依次被#improt(A->B, B->C,C->D…),一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍,这样的效率也是可想而知的,而相对来 讲,使用@class方式就不会出现这种问题了;
4、对于循环依赖关系来说,比方A类引用B类,同时B类也引用A类,B类的代码:
  1. #import "A.h"    
  2. @interface B : NSObject {   
  3.   
  4.     A *a;   
  5. }   
  6. @end
当程序运行时,编译会报错, 当使用@class在两个类相互声明,就不会出现编译报错。

>类接口的声明以@interface开头以@end结尾。 在其中声明属性和方法。

@interface ClassName :ItsSuperclass
{
     // Instance variable declarations.    // 实例变量的声明
}
// Method and property declarations.  // 方法和属性的声明
@end

>类的实现  以@implementation开头,@end结尾 可能会在@implementation后面的大括号中声明实例变量
@implementation ClassName
{
     // Instance variable declaration  // 实例变量的声明
}
// Method definitions.   方法的定义
@end

第二节  成员变量、属性、方法

>成员变量

成员变量(Member variable):上图中括号里面的统称为“成员变量”。
实例变量 (Instance variable):实例变量是成员变量中的一种。即实例变量由类定义的变量,除去基本数据类型int float..等,其他类型的变量都叫实例变量
**实例变量+基本数据类型变量=成员变量**
成员变量用于类的内部,无需与外界接触的变量。因为成员变量不会生成set、get方法,所以外界无法与成员变量接触。
一般使用的时候为_name,点语法调用的就是访问器方法(set/get)
.m文件中,self.name 这样的表达式是错误的。xcode会提示你使用->,改成self->name就可以了。因为oc中点表达式是表示调用方法,而上面的代码中没有name这个方法。(set/get方法)
 oc语法关于点表达式的说明:"点表达式(.)看起来与C语言中的结构体访问以及java语言汇总的对象访问有点类似,其实这是oc的设计人员有意为之。如果点表达式出现在等号 = 左边,该属性名称的setter方法将被调用。如果点表达式出现在右边,该属性名称的getter方法将被调用。"

>属性变量
@property (描述1,描述2,描述3) (class *)varName;  // 属性的样式
描述1: nonatomic <--->  atomic (原子性和非原子性)
描述2:readwrite <—>readonly  (读写)
描述3:retain/copy/assign
retain: 指的是讲某个内存区域的指针赋给变量,同时把该内存区域的引用计数器加1.每执行一次,该内存区域的引用计数器就要加1,当该区域的引用计数器变为0的时候,内存被释放!
copy:指的是将目标内存区域的值复制一份,然后开辟新的内存区域(新的指针)粘贴这个值。同时变量被赋值为新内存区域的指针!
assign:指的是仅把目标内存区域的指针赋值给变量,该内存区域的引用计数器不发生变化!

这三个都是指的,在自动生成setter函数的时候,编译器需要识别描述词来生成对应的setter函数,需要注意的是,如果没有加上该类的描述词,系统默认该变量的setter方法采用assign的方式.

因为编译器会自动为你生成以下划线开头的实例变量_myButton,不需要自己手动再去写实例变量。而且也不需要在.m文件中写@synthesize myButton;也会自动为你生成setter,getter方法。@synthesize的作用就是让编译器为你自动生成setter与getter方法。
@synthesize 还有一个作用,可以指定与属性对应的实例变量,例如@synthesize myButton = xxx;那么self.myButton其实是操作的实例变量xxx,而不是_myButton了。

属性和变量的区别:属性变量在创建的过程中自动产生了set和get方法,主要用于与其他对象交互的变量。成员变量则是用于类内部的私有变量,不会生成set、get方法。

>方法
开头为负号(-)的方法为实例方法,被对象指针调用。
开头为正好(+)的方法表示为类方法,类方法是对类本身执行某些操作的方法。(1.便利构造器 2.单例 3.纯过程封装)

       -          (void)      setNumerator           :                  (int)                n;
方法类型    返回类型        方法名称        方法有参数      参数类型     参数名称

0 0