(一)学习目标:
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/
没什么意义就是为了解释类的整个创建过程。 我们先前描述的三个方法: 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:]; //调用实例方法
[myFraction setDominator:];//调用实例方法
[myFraction print]; //调用实例方法
[myFraction release]; //释放存储空间
[pool drain];
return ;
}
我们首先需要创建一个类的实例 myFraction,然后为myFraction 分配存储空间 myFraction = [Fraction alloc]; 然后初始化 myFraction (包括了实例变量的初始化,实例方法的初始化)myFraction = [myFraction init]; 然后我们就可以使用 setNumerator 和 setDominator 以及print 方法了。
因为没有返回值,所以格式就是 [myFraction setNumerator:]; 表示调用 myFraction 的 setNumerator 方法,setNumerator这个方法执行后将为 numerator 这个实例变量赋值 也就是说 numerator 的值被设定为 。 为了将最后的结果打印出来,我们使用了[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网站上,搜集起来仅供参考。