Objective-c 总结,一:OC类的设计

(一)学习目标:

1.面向对象基本概念:

OOP的主要思想是把构成问题的各个事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描述一个事物在整个解决问题步骤中的行为。

2.熟悉OC类的定义:

OC类分为两个文件,.h 和 .m文件

.h 文件存放类、函数声明,类声明用关键字@interface @end 来声明

.m文件存放的是具体实现,类实现使用关键字@implementation @end 来实现

+ 表示类的方法,相当于 JAVA中的静态函数

- 表示对象方法,对象实例化可以调用

3.熟悉OC的字段定义:

@interface Person : NSObject
 {
      int age;  //字段在此定义
 }
 - (void)setAge:(int)newAge; //函数在此定义
 @end

-(int) f:(int)x
函数模型从左到右说明
1、-或+表示对象函数或类函数,
2、(int)表示返回值
3、f:表示函数名称
4、(int)x表示函数形参

变量申明:@public @protected @private

  O-C中变量必须定义在类{}之间的地方

  O-C缺省是@protected

  O-C里面的函数全是@public类型 没有其他的类型(用另外的方式实现private化)

创建对象

  Dog *dog=[Dog alloc];

  初始化构造函数

  [dog init];

  销毁对象

   [dog release];

OC有别于C/C++的一些比较

  1、BOOL  YES  NO

   在oc中布尔类型是BOOL,布尔值是yes,no

  2、id类型

    O-C中每个目标都可以表达为id类型,可以认为是NSObject*或者是void*

  3、nil

    nil表示null,表示一个目标指针
    • 函数类型C++Object-C
      无参数int say();

      int res = obj->say();

      -(int) say;

      int res = [obj say];

      一个参数int say(int a);

      int res = obj->say(1);

      -(int) say:(int)a;

      int res = [obj say:1];

      两个参数int say(int a,int b);

      int res = obj->say(1,3);

      -(int) say:(int)a :(int)b;

      int res = [obj say:1 :3];

      带标签int sayAndWrite(int a,int b);

      int res = obj ->sayAndWrite(1,3);

      -(int) say:(int)a andWrite:(int)b;

      int res = [obj say:1 andWrite:3];

4. 熟悉OC函数定义的规则:

- (void) doIt:(NSString *) actorName movieName: (NSString*) value timesSeen: (int)times { 
NSLog(@"%@ is my favorite actor in the movie %@, I saw it %i times.",actorName, value, times); 
}

1、'-'表示这个函数是实例函数(类似非静态函数),'+'表示这个函数是类函数(类似静态函数)

2、(void)表示这个函数没有返回值。

3、函数名是'doIt: movieName: timesSeen:',而不是'doIt'

4、参数用空格隔开

5、参数类型写在括号中

6、参数分内部参数和外部参数,如电影名称,内部参数是:value,外部参数是:movieName

5.+函数与-函数有什么不同?

+函数类方法,-函数实例方法

类方法,也称静态方法,指的是用static关键字修饰的方法。此方法属类本身的方法,不属于类的某一个实例(对象)。类方法中不可直接使用实例变量。其调用方式有三种:可直接调用、类名.方法名、对象名.方法名。实例方法指的是不用static关键字修饰的方法。每个实例对象都有自身的实例方法,互相独立,不共享一个。其调用方式只能是对象名.方法名。

用修饰符static声明的方法为静态方法,不用修饰符static声明的方法为实例方法。不管类生成或未生成对象,类的静态方法都可以被使用,使用格式为:类名.静态方法名。静态方法只能使用该静态方法所在类的静态数据成员和静态方法。这是因为使用静态方法时,该静态方法所在类可能还没有对象,即使有对象,由于用类名.静态方法名方式调用静态方法,静态方法没有this指针来存放对象的地址,无法判定应访问哪个对象的数据成员。在类创建对象后,实例方法才能被使用,使用格式为:对象名.实例方法名。实例方法可以使用该方法所在类的所有静态成员和实例成员。

何时用静态方法,何时用实例方法?

先说实例方法,当你给一个类写一个方法,如果该方法需要访问某个实例的成员变量时,那么就将该方法定义成实例方法。一类的实例通常有一些成员变量,其中含有该实例的状态信息。而该方法需要改变这些状态。那么该方法需要声明成实例方法。

静态方法正好相反,它不需要访问某个实例的成员变量,它不需要去改变某个实例的状态。我们把该方法定义成静态方法。

关于静态方法和实例方法的一些误区。

静态方法常驻内存,实例方法不是,所以静态方法效率高但占内存。

事实上,方法都是一样的,在加载时机和占用内存上,静态方法和实例方法是一样的,在类型第一次被使用时加载。调用的速度基本上没有差别。

静态方法在堆上分配内存,实例方法在堆栈上。

(二)讲义内容:

1. NSLog 使用:

1、NSLog会自动加上换行符,不需要自己添加换行符,NSLog会加上时间和进程信息,而printf仅将输入的内容输出不会添加任何额外的东西。

2、打印字符串

NSLog(@”hello , Objective-C !”);

3、c字符串是字符串数组,NSString字符串是oc对象,不能动态更改。

2. 定义一个类:

类的.h 和 .m 概念:

.h :头文件。头文件包含类,类型,函数和常数的声明。

.m :源代码文件。这是典型的源代码文件扩展名,可以包含Objective-C和C代码。

.mm :源代码文件。带有这种扩展名的源代码文件,除了可以包含Objective-C和C代码以外还可以包含C++代码。仅在你的Objective-C代码中确实需要使用C++类或者特性的时候才用这种扩展名

如何定义一个类:

创建对象

Dog *dog=[Dog alloc] ; 一个类的名字 + alloc

初始化构造函数

[dog init];    凡是以init…开头的都是构造函数

销毁对象

[dog release];

创建一个 OC 类需要编写两个部分  @interface 和 @implementation

@interface 专门用于类的描述,描述的内容包括:实例变量的名称和类型,以及实例变量的方法,当然了,在描述“方法”的时候是会指明它的名称,是否具有返回值,是否用到参数等等。例如:

@interface Fraction: NSObject
{
    int numerator; //定义实例变量
    int denominator; //定义实例变量
}
-(void) print; //定义了名称为print的,一个没有返回值的实例方法
-(void) setNumerator:(int) n;
-(void) setDenominator:(int) d;
@end
Fraction 是我们创建类的名称 Fraction: NSObject 表示Fraction继承了NSObject类。
int numerator; 是定义一个实例变量,它的类型是“整数”
-(void) setNumerator; 是定义一个实例方法,“-”号表示 “实例方法”,如果是“+”则表示类的方法,后面(int)n;表示这个方法用到的参数名称为n,它的类型为整型,void 表示这个方法没有返回值。

那么什么是类的方法,什么又是实例的方法呢?

用一个简单的例子,是最好的解释。假设我们有一个类的名字叫做 Car,我需要创建一个新的对象:myfirstcar,如何来做呢?
myfirstcar = [Car creatCar];
然后我需要为我的车加油,如何来做呢?
[myfirstcar getOil]
其中, creatCar 就是类方法, getOil就是实例方法。由此可见,类方法只能操作“类本身”,或者用来创建一个实例对象,而实例方法则是对实例进行相关的操作。

类的描述部分结束了,我们需要对类描述的方法进行“代码填充”,如果只描述个名称而不给它实际的内容,很显然是没有任何意义的。

@implementation Fraction
-(void)print
{
  NSLog(@"%i/%i",numerator, denominator);
}
-(void)setNumerator:(int)n
{
  numerator = n;
}
-(void)setDenominator:(int)d
{
 denominator = d;
}
@end
看到这里大家基本应该明白了这个类的作用就是打印一个分数,比如 定义分子是1 分母是2 打印出来1/2
没什么意义就是为了解释类的整个创建过程。

我们先前描述的三个方法: print setNumerator setDenominator 在这里被详细的写出了内容代码。
有点类似于函数的定义 
@implementation 后面跟的是类名Fraction,可别写错了。

截至到这里,一个完整的类就被定义出来了。那么我们如何使用它呢?

#import <Foundation/Foundation.h>
    int main (int argc, char *argv[]) {
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
        Fraction *myFraction;
        myFraction = [Fraction alloc]; //分配存储空间
        myFraction = [myFraction init];  //初始化实例变量 myFraction
        [myFraction setNumerator:1]; //调用实例方法
        [myFraction setDominator:3];//调用实例方法
        [myFraction print]; //调用实例方法
        [myFraction release]; //释放存储空间
        [pool drain];
        return 0;
    }
我们首先需要创建一个类的实例 myFraction,然后为myFraction 分配存储空间 myFraction = [Fraction alloc]; 然后初始化 myFraction (包括了实例变量的初始化,实例方法的初始化)myFraction = [myFraction init];

然后我们就可以使用 setNumerator 和 setDominator 以及print 方法了。
因为没有返回值,所以格式就是 [myFraction setNumerator:1]; 表示调用 myFraction 的 setNumerator 方法,setNumerator这个方法执行后将为 numerator 这个实例变量赋值 也就是说 numerator 的值被设定为 1 。

为了将最后的结果打印出来,我们使用了[myFraction print]; 

这就是一个类从创建到使用的完整过程

OC 中基本类型定义 id, BOOL:

在Objective-C 中,id 类型是一个独特的数据类型。在概念上,类似Java 的Object 类,可以转换为任何数据类型。换句话说,id 类型的变量可以存放任何数据类型的对象。在内部处理上,这种类型被定义为指向对象的指针,实际上是一个指向这种对象的实例变量的指针

typedef signed char BOOL;

#define YES      (BOOL) 1
#define NO       (BOOL) 0

4. 定义一个类字段:

字段定义

三种作用域:@public @protected(保护,在类本身或者子类中) @private (只能在类的内部)

补充:缺省的是protected

函数全部用public

变量必须定义在类{}之间的地方

注:在c中函数和字段是可以重名的

#import <Foundation/Foundation.h>

@interface Student : NSObject {
    int age; // 年龄
    
    @public
    int no; // 学号
    int score; // 成绩
    
    @protected
    float height; // 身高
    
    @private
    float weight; // 体重
}

@end

  

用类的定义来创建一个实例,就叫做类的实例化。

5. 类和实例的区别

方法根据是否有static修饰也可以分为类方法和对象方法(实例方法)。
访问时,类方法可以直接通过类名来引用,而实例方法必须通过对象名来访问,也就是说要想使用实例方法,就必须创建一个该类的对象。
Math类的方法都是类方法,在使用时,可以如下:
double s=Math.sin(30);
Properties prop=System.getProperties();
一般而言,类方法的执行不依对象而改变。在定义方法时,一些与对象无关的通用方法通常被定义为类方法。由于类方法是属于整个类的,并不属于哪个对象,所以类方法的方法体中不能有与类的对象有关的内容,所以出现下面的情况的时候会出现编译错误:
1 类方法中不能引用对象变量
2 类方法中不能调用类的对象方法
3 在类方法中不能使用super、this关键字。
使用对象方法时,必须先创建对象实例,然后才能使用,如:
Student stu=new Student("0701956");
stu.showAcademicRecord();
与类方法相比,对象方法基本上没有什么限制:
1 对象方法可以引用对象变量,也可以引用类变量
2 对象方法中可以调用类方法
3 对象方法中可以使用super、this关键字。

  

Ps : 定义以及解释摘抄于IT网站上,搜集起来仅供参考。