1、OC是在C语言基础上进行扩展得到的一门面向对象的程序设计语言,它也提供了定义类、成员变量和方法的基本功能。类可以被认为是一种自定义的数据类型,使用它可以定义变量,所有使用类定义的变量都是指针类型的变量,他们将会指向该类的对象。类用于描述客观世界中某一类对象的共同特征,而对象则是类的具体存在。
2、类的定义:OC中定义类分为两个步骤,接口部分和实现部分。OC学习篇之---类的定义
接口部分:定义该类包含的成员变量和方法
实现部分:为该类的方法提供实现
3、接口定义用@interface关键字,用@end表明定义结束,其中紧跟该类的一队花括号用于声明该类的成员变量,花括号后面的部分用于声明该类的方法。一般接口部分的定义格式和实现为:
@interface 类名:父类{
//定义属性,只定义,不赋值
属性类型 属性名;
} //定义方法,只定义,不实现
-/+方法类型标识符 (返回值类型) 方法名:形参名 形参标签2:形参2; @end
@interface Person : NSObject{
//在{}中定义属性(全局变量/实例变量)
//注意:只能定义不能赋值,因为这里只是在做声明操作,不能赋值的
//加上下划线,为了区*部变量
NSString *_name;//姓名,默认值是nil:空指针,可以查看定义:#define nil NULL
NSInteger _age;//年龄,默认值是0
} //定义方法
//-:实例方法,+:类方法
//格式:方法说明 (返回类型) 方法名 : (参数类型)参数名称
//注意方法名是shopping:,不是shopping,这个要注意
- (void)shopping:(float)price; //定义方法设置属性值(注意setXXX)
- (void)setName:(NSString *)name;
- (void)setAge:(NSInteger)age; //定义方法的获取属性值(注意不是getXXX,而是直接的属性名,因为getXXX在OC中还有其他用途),没有形参则可以省略冒号
- (NSString *)name;
- (NSInteger)age; //多个参数的方法定义
//方法名两部分组成的:setName: setAge:
- (void)setName:(NSString *)name setAge:(NSInteger)age;
//或者方法名:setName: :,后面的可以省略,但是这种方式不建议使用
//- (void)setName:(NSString *)name :(NSInteger)age; //类方法
//在这个方法中是无法访问属性的,因为属性是属于对象的,不是类的
+ (Person *)newPerson;
@end
- 成员变量:成员变量命名一般都是以下划线开头, 避免与局部变量冲突
- 方法类型标识符:该标识符要么是+,要么是-,其中,+表示该方法是类方法,相当于Java中的静态方法,通过类名可以直接调用;-代表该方法是实例方法,需要通过实例对象来调用。
- 方法返回值类型:OC中方法的返回值类型可以是OC允许的任何任何数据类型,包括基本类型、构造函数和各种指针类型。
- 方法签名关键字:OC的方法签名关键字由方法名、形参标签和冒号组成。如果方法没有形参,则可以省略冒号,像上面的获取属性值的方法
4、类的实现部分:接口部分只是对类的成员变量和方法进行声明,并没有为方法提供实现的方法体。类的实现用@implementation关键字进行标识,用@end表示结束。上述Person类的接口定义对应的实现如下。
@implementation Person //实现方法
- (void) shopping : (float)price{
NSLog(@"%@ shopping %f",_name,price);
} - (void)setName:(NSString *)name{
_name = name;
}
- (void)setAge:(NSInteger)age{
_age = age;
}
- (NSString *)name{
return _name;
}
- (NSInteger)age{
return _age;
}
- (void)setName:(NSString *)name setAge:(NSInteger)age{
_name = name;
_age = age;
}
+ (Person *)newPerson{
return [[Person alloc] init];
} @end
- 类实现部分的类名必须和类接口部分的类名相同,用于表示这是同一个类的接口部分和实现部分。
- 类实现部分也可以在类名之后使用“:父类”来表示继承了某个父类,但是一般没有必要,因此,通常都不会这么做。
- 类实现部分必须为类声明部分的每个方法提供方法实现。实现部分除了实现类接口部分定义的方法之外,也可以提供额外的方法定义——这些没有在接部分定义,只在实现部分定义的方法只能在类实现部分使用。同样,实现部分也可以定义成员变量,但是该成员变量只能在实现部分使用。实现部分额外定义的成员变量和方法相当于Java中的private变量和方法。
5、根据习惯,接口部分和实现部分分别使用两个源文件进行保存,通常接口部分在.h文件中对类进行定义和声明,而实现部分则在.m文件中进行实现,这样可以更好地实现面向对象的封装特性,只需要向外暴露接口部分以供调用,实现部分则属于该类的内部实现,对于外界而言是隐藏的。
6、对象的产生和使用:当一个对象被创建成功之后,这个对象将保存在堆内存中,OC不允许直接访问堆内存中的对象,只能通过该对象的指针变量来访问该对象。如果堆内存中的对象没有任何变量指向该对象,那么程序将无法再访问该对象,OC没有提供自动的垃圾回收机制,需要程序员自己释放该对象所占用的内存,否则就会造成内存泄漏。
//类的定义放在.h文件中
//类的实现放在.m文件中 #import <Foundation/Foundation.h>
#import "Person.h" int main(int argc, const charchar * argv[]) {
@autoreleasepool {
//创建对象
//在内存中申请一块内存区域
//Person *person = [Person alloc];
//调用初始化方法,初始化一些默认数据
//可能上面申请的内存之前有被使用过,还会有以前的数据。所以我们需要将其数据清空,这时候就会将默认值进行赋值(相当于清空操作)
//person = [person init]; //合并
//这里申请了两块内存:一个是对象指针变量person,一个是alloc申请的保存Person对象的内存
//可以看出alloc/init方法是类方法、可以查看NSObject对象的定义,alloc相当于给这个对象分配内存空间,init是调用这个类的构造方法,对属性和字段进行初始化操作
Person *person = [[Person alloc] init]; //还有另外的一种方式创建一个对象,但是这种方式不建议使用,因为这种方式相当于把上面的两个合并
//有时候我们需要将上面的两个步骤进行分开操作的
//Person *person1 = [Person new]; //设置名字
[person setName:@"jaingwei"]; //调用实例方法shopping
[person shopping:]; Person *person1 = [[Person alloc] init];
[person1 setName:@"huangdaoyang"];
[person1 shopping:];
//同时设置两个属性的值,但是这种方式不建议使用,建议使用set方法
[person1 setName:@"huangdaoyang" setAge:]; //get方法调用
NSString *person_name = [person name];
NSLog(@"name is %@",person_name);
NSString *person1_name = [person1 name];
NSLog(@"name is %@",person1_name); //类方法调用
Person *person2 = [Person newPerson];
[person2 setName:@"shixin" setAge:];
[person2 shopping:]; //空指针
Person *person3 = nil;
//不执行任何操作,但是也不会报错空指针异常
[person3 setName:@"空对象" setAge:];
}
return ;
}
7、 类的初始化方法init相当于Java中的构造方法,但是OC中没有默认的init方法,必须自己实现。此外,我们还可以进行自定义初始化方法,对对象的成员变量进行初始化赋值,但是自定义的初始化方法必须以init开头命名。具体的接口分布和实现部分的示例代码如下:
@interface Person : NSObject{
NSString *_name;
NSInteger _age;
} //自定义初始化方法,必须以init开头
- (id)initWithName:(NSString *)name withAge:(NSInteger)age; //打印信息
- (void)showInfo; @end
@implementation Person - (id)initWithName:(NSString *)name withAge:(NSInteger)age{
//固定写法,可以背下来哦~~
//调用父类的初始化方法
self = [super init]; if(self != nil){
_name = name;
_age = age;
} return self;
} - (void)test{
NSLog(@"test");
} - (void)showInfo{
[self test];//调用自己的方法
NSLog(@"name is %@ and age is %d",_name,_age);
} @end
- OC中提供了一个self关键字,与Java中的this关键字类似。self关键字总是指向该方法的调用者(对象或类),当self出现在实例方法中时,self代表调用该方法的对象;当self出现在类方法中时,self表示调用该方法的类。self关键字的最大的作用是让类中的一个方法访问该类中的另一个方法。此外,当形参或局部变量的变量名和成员变量的变量名相同时,可以用“self->变量名”来强行制定访问访问成员变量。此外还有super关键字则与Java中的super一样,都是指代父类。
- id类型:OC提供了一个id类型,这个id类型可以代表所有对象的类型,也就是说,任意类的对象都可以赋值给id类型。当通过id类型的变量来调用方法时,OC将会执行动态绑定。所谓动态绑定,是指OC将会跟踪对象所属的类,它会在运行时判断该对象所属的类,并在运行时确定需要的动态调用的方法,而不是在编译时就确定要调用的方法。
8、OC中方法的所属性主要体现在如下几个方面:
- 方法不能独立,只能在类体中定义
- 从逻辑上看,方法要么属于类体本身,要么属于该类的一个对象
- 不能独立调用方法,调用方法需要使用类或对象作为调用者
9、在方法定义时我们有时候需要允许方法根据需要传递不确定个数的参数,即形参个数可变的方法在OC中是可以实现的,类似OC中的NSLog()函数就可以传入任意多个参数。如果在定义方法时,在最后一个形参名之后曾加都好和三点(,...),则表明该形参可以接受多个参数值。
为了在程序中获取多个可变的形参,需要使用到如下关键字:
- va_list:这是一个类型,用于定义指向可变参数列表的指针变量
- va_start:这是一个函数,该函数制定开始处理可变形参的列表,并让指针变量指向可变形参列表的第一个参数。
- va_end:结束处理可变形参,释放指针变量。
- va_arg:该函数返回获取指针当前指向的参数的值,并将指针移动到下一个参数。
#import <Foundation/Foundation.h> @interface VarArgs:NSObject
//不定义成员变量,直接定义可变参数的方法
- (void) test : (NSString *) name, ...;
@end @implementation VarArgs
- (void) test : (NSString *) name, ...
{
//使用va_list定义一个argList变量,该指针指向可变参数列表
va_list argList ;
//如果第一个name存在才需要处理后面的参数
if(name)
{
//由于name参数并不在列表里,因此先处理name参数
NSLog(@"%@", name) ;
//使用va_start方法让argList指向参数列表的第一个元素
va_start(argList,name) ;
//使用va_arg依次提取argList中的参数
NSString * str ;
while(str = va_arg(argList,id))
{
NSLog(@"%@", str) ;
}
//释放argList指针,结束提取
va_end(argList) ;
}
}
@end int main(int argc, char * argv[])
{
VarArgs * va = [[VarArgs alloc] init] ;
[va test:@"疯狂IOS讲义", @"疯狂iosj讲义", @"i love ios", nil] ;
}
OC学习5——类和对象的更多相关文章
-
Javascript学习6 - 类、对象、继承
原文:Javascript学习6 - 类.对象.继承 Javasciprt并不像C++一样支持真正的类,也不是用class关键字来定义类.Javascript定义类也是使用function关键字来完成 ...
-
《python基础教程(第二版)》学习笔记 类和对象(第7章)
<python基础教程(第二版)>学习笔记 类和对象(第7章) 定义类class Person: def setName(self,name): self.name=n ...
-
OC第一节 —— 类和对象
一.类和对象的概念 1.1类 自己的定义: 具有相同或相似性质对象的抽象. 1.2 对象 自己的定义: 对象是人们要进行研究的任何物体,从最简单的整数到复杂的飞机 等均可以看做是对象. 举例说明: 类 ...
-
[Java初探08]__简单学习Java类和对象
前言 在前面的学习中,我们对面向对象的编程思想有了一个基本的了解,并且简单的了解了类和对象的定义.那么类和对象在Java语言中是如何表现的,这次,就从实际出发,学习一下一下类和对象在Java语言中的使 ...
-
Java学习笔记--类和对象
1.介绍面向对象的编程 面向对象是现在主流的编程样例,它替代了以前C语言使用时的“结构体”,Java是一门面向对象的语言,所以需要熟悉面向对象的概念.面向对象的程序由很多对象组成,每 ...
-
OC开发系列-类与对象
面向对象 面向对象思想是一种解决问题的思想, 不在是面向过程的去思考问题怎样解决.面向对象解决问题时首先要考虑需要找几个对象能解决这个问题. 常见的概念: * Object Oriented 面向对象 ...
-
scala学习笔记——类和对象
基础语法关于Scala程序,这是非常要注意以下几点. 区分大小写 - Scala是大小写敏感的,这意味着标识Hello 和 hello在Scala中会有不同的含义. 类名 - 对于所有的类名的第一个字 ...
-
学习:类和对象——对象模型和this指针
成员变量和成员函数分开存储: 在C++中,类内的成员变量和成员函数分开存储 第一点:空对象占用内存空间1个字节 第二点:只有非静态成员变量才属于类的对象上,非静态成员函数和静态成员函数和静态成员变量不 ...
-
Python学习笔记——类和对象
类和对象 1. 一个例子 # 对象 = 属性 + 方法 # Python 中的类名称约定首字母大写,而 Python 函数名首字母小写 class Turtle: #属性 color = 'green ...
随机推荐
-
js仿微信语音播放
html结构如下: <div class="app-voice-you" voiceSrc="xx.mp3"> <img class=&quo ...
-
使用Apache2配置多个站点
六 27 pache2主配置文件: /etc/apache2/apache2.conf.其最后两行为: # Include the virtual host configurations:Incl ...
-
swift 当协议遇见了泛型
由于泛型比较简单,并没有单独拿出来介绍!我们在定义函数的时候,有时候只是由于参数或者返回值类型不同,而具体的实现过程是一模一样的,这个时候我们就可以定义泛型函数而使可以传入不同的参数类型: func ...
-
SSIS包配置动态配置数据库连接
动态连接数据库便于维护 用SSIS包配置实现 1.控制流页签 - 右键 - 包配置 2.配置xml文件 3.指定连接属性:ServerName.UserName.Password 测试: 1.配置错误 ...
-
scrapy_ip_agent
#File name is rotate_useragent# -*- coding: UTF-8 -*- import randomimport urllib2import redisfrom sc ...
-
[OpenCV学习笔记1][OpenCV基本数据类型]
CvPoint基于二维整形坐标轴的点typedef struct CvPoint{int x; /* X 坐标, 通常以 0 为基点 */int y; /* y 坐标,通常以 0 为基点 */}CvP ...
-
OC语言(三)
十九.一些规范 import系统自带的用尖括号<>来包含. 发现需求不清晰,一定要先搞明白才去做. 多文件开发,文件名和类名一致 命令行里的做法:(只是编译链接主文件,但是全部编译链接会出 ...
-
C#图片裁切,生成新图片
/// 图片裁剪,生成新图,保存在同一目录下,名字加_new,格式1.png 新图1_new.png /// </summary> /// <param name="pic ...
-
CSS 样式中的两个方法
在很多时候,我们需要LI开头空一点距离.结尾不能再有下划线了.这个效果在以前是很难实现的.但是有了下面两个选择器,非常容易做出这种东西. .slideTxtBox .bd ul > :first ...
-
Spring RPC 入门学习(2)-获取Map对象
Spring RPC传递Map用例编写 1. 新建RPC接口类 package com.cvicse.ump.rpc.interfaceDefine; import java.util.Map; pu ...