黑马程序员--06OC类和对象
来源:互联网 发布:谷歌浏览器禁止js 编辑:程序博客网 时间:2024/05/22 14:31
1.类
1.类的设计
1. 设计类只需要关注三部分:
类的名称 - 人(Person)
具有属性 - 比如姓名(name), 年龄(age)
具有功能 - 比如吃饭(eat), 运动(sport)
2. 类名的规范
a. 类名的第一个字母必须大写
b. 不能有下划线
c. 多个英文单词用驼峰标识
2类的创建和使用
如何用OC创建类 完整的写一个函数需要: 函数的声明和实现.
完整的写一个类需要: 类的声明和实现.
3.类的声明
1 格式:
类的声明以@interface开头, 以@end结尾
类的声明必须要说明父类, 并import父类的声明文件
类的声明中要说明属性和声明行为(成员变量和方法声明)
2 属性:
属性声明在大括号中.
属性也叫做成员变量或者实例变量(每个实例都有自己的属性值).
对象创建时, 所有的成员变量默认初始化为0. 只能声明成员变量, 不能在大括号里给它们赋初值. 只写类型和变量名. 也不能用static等等修饰.
@public可以让外部的指针直接访问对象的成员变量. @public后面的属性都是public属性
3 方法:
方法声明写在大括号外面.
方法由三部分构成:方法名,参数,返回值
OC中方法要遵循下面的要求:
a> 如果是对象调用的方法, 用减号标记. 如果是类调用的方法, 用加号标记.
b> 数据类型用()括起来
c> 接收的参数不能用()括, 因为在OC中小括号就是用来括数据类型的. 参数要用冒号标记. 有几个参数就写几个冒号. 没有参数就不写.
方法不能使用static修饰. static是修饰C语言的函数的. 方法和函数不同.
4.类的实现 :用来实现@interface中声明的方法
1 类的实现要以@implementation开头, 以@end结尾 , 类的实现中不需要写父类。
2 方法的实现, 先把方法声明抄过来, 再加个大括号, 在里面写实现代码。 方法内部如果要访问当前对象的成员变量, 直接写变量名字就可以
5.类的使用
1 在OC中执行一个行为要使用中括号的格式: [行为执行者 行为名称], 即告诉OC让那个执行者去执行那个行为.
2 OC中操作对象只能通过指针来操作, 不能直接操作对象
3 类的声明必须放在main之前, 跟函数一样, 因为编译是从上往下的.
#import <Foundation/Foundation.h>//类的声明。NSObect中包含new方法,没有这个继承Car就无法创建对象//OC中想要修改某个变量的只能用指针@interface Car : NSObject{@public // 可以让外部指针访问类的成员变量 int wheels; // Car这个类的成员变量 int speed;}//OC对象方法必须以-开头//OC方法中任何数据类型用括号扩住()//在OC中,括号中只能用来扩住数据类型,不能乱用的- (void)test;@end//类的实现@implementation Car- (void) test{ NSLog(@"车子跑起来了");}@endint main(){ //[Car new]会创建一个新的对象,并且返回该对象的地址 Car *p = [Car new]; p->speed = 250; p->wheels = 4; [p test]; NSLog(@"车子有轮子%d个,车子速度%d",p->speed,p->wheels); return 0;}
1[Car new]; 这句执行Car这个类的new行为. 在内存中开辟一块存储空间给Car对象, 这个对象中有两块int空间存储它的属性wheels和speed,并被初始化为0.
在main结束时, 这块内存被销毁, 空间被回收.
2
Car *p; 定义一个指针变量来指向[Car new]创建的新对象(new返回对象地址)
3
p->wheels=4; 使用这个指针来访问对象的属性 (OC对象的本质其实就是结构体). 如果属性声明中没有@public就不可以通过指针这样访问.
4
[p run]; 调用p指向的对象的run方法 (也叫做发送消息)
@interface Person : NSObject{ @public int age; int weight;}- (void) run;@end@implementation Person- (void) run{ NSLog(@"%d岁,%d重的人跑了一步",age,weight); // 对像方法中的变量直接调用对象中的变量}@endint main(){ Person *p = [Person new]; p->age = 20; p->weight = 100; Person *p1 = [Person new]; p1->age = 24; p1->weight = 120; [p1 run]; Person *p3 = [Person new]; p3 = p; p3->age = 50; // 改变了最上边生产的对象的成员变量 [p run]; return 0;}
6.类在内存中的存储
类在内存中也占据存储空间, 一个类只占一份存储空间. 每个对象都占一份存储空间.
类的存储空间里只存放方法列表. 使用类创建对象之前, 会先给类分配一块存储空间, 把类加载进内存且只加载一次. 每个对象内部都有一个isa指针, 指向类所在的内存空间.
每当新建一个对象时, 都会在内存中分配一块存储空间给对象, 这块空间内部储存对象的成员变量, 还有一个isa指针指向类的空间(里面可以访问到类的方法).
使用指针访问对象的成员变量时, 访问当前对象的成员变量. 使用指针调用方法时, 访问的成员变量也是当前对象的成员变量. 类中只存储方法列表。对像中包含成员变量和isa
例子 : [p run]; 给p所指向的对象发送run消息,来到此对象后,要调用run方法,顺着isa指针找到他自己的类,在类中找到run方法后调用代码。
2.对象
1.对象与函数
位置:函数可以在文件的任意地方定义(除了类的声明里),函数是属于整个project所有的, 所以其实可以写在任何地方. 函数甚至可以写在@implementation里面, 和写在外面的效果是一样的.
方法必须声明和实现在类的定义里.
定义:函数的定义方式是C语言的方式, 没有加减号, 参数在小括号里, 类型不用括号 如 void sum(a,b);. 方法的定义需要加减号, 小括号里是类型, 参数用冒号标记 如 - (int) sum: (int) a :(int) b;
调用:调用时, 函数使用函数名(参数)方式 sum (3,2), 方法使用[对象名 方法名]方式调用 [p sum:3:2];.
对象方法只能由对象调用,其归对象所有
函数的调用不依赖于对象,但函数内部不能直接通过成员变量名访问某个对象的成员变量
方法可以作为函数的参数
#import <Foundation/Foundation.h>@interface Person : NSObject{ @public int age; int weight;}- (void) run;@end@implementation Person- (void) run{ NSLog(@"%d岁,%d重的人跑了一步",age,weight); // 对像方法中的变量直接调用对象中的变量}@endvoid test(Person *S1){ Person *s= [Person new]; s->age = 1; s = S1; // 只是将S1中包含的地址给了s,将s原来的地址给覆盖了,不会影响p}int main(){ Person *p = [Person new]; p->age = 20; p->weight = 100; test(p); [p run]; return 0;}
- (void)test 这种写法肯定是不对的,只能是[p test]
还有函数出了@interface与@end中间不能写,其他地方都能写,方法有严格的限制。
2关于方法名
- (int) square:(int)num; 这个方法的方法名是 square: 冒号是方法名的一部分. 比如 - (int) square; 这个方法的方法名是square. 这两个方法的名称是不一样的.
- (int) sumOfNum1:(int)num1 andNum2:(int)num2; 这个方法的方法名是 sumOfNum1: andNum2:
加减号不是方法名的一部分, 而是方法类型.
关于有多个参数方法的写法
- (int) sumOfNum1:(int)num1 andNum2:(int) num2;
1) 每个形参名称后面要有空格, 和后面的方法名部分分隔
类方法 - 使用类名来调用的方法.以 + 标记.
使用场合: 使用类方法代替对象方法可以提高性能.
类方法比对象方法优化体现在不用创建对象就能执行行为.在内存中, +识别为类方法,直接去类的存储空间中调用方法. 对象方法则需要通过对象指针访问对象,通过isa指针访问类空间,才能调用到方法.对象方法中可以包含类方法
+开头的方法和 -开头的方法是不同的.类不能调用对象的方法, 对象不能调用类的方法.否则(编译链接可以通过)运行时会报错 -找不到相应的类/对象方法.
因为类方法和对象方法不同, 所以可以有同名的类方法和对象方法.
+ (void) test;
- (void) test;
上面两个方法是可以同时存在的.但是不能有两个同名的对象方法或两个同名的类方法.
注意: 成员变量也叫实例变量,是只有实例(对象)才有的变量,类没有成员变量. 在内存中,对象里有存储空间存放成员变量的值,类的空间里是没有存放成员变量的地方的,所以类没有成员变量的值,类方法不能访问成员变量.
所以, 如果方法中需要访问成员变量,就要写成对象方法. 如果不需要访问成员变量,就可以写成类方法.
类方法注意:
a.不依赖于对象,执行效率高.
b.能用类方法(不需要成员变量)尽量用类方法.
c. 当方法内部不需要访问成员变量时,就可以使用类方法.
#import <Foundation/Foundation.h>@interface Person : NSObject{ @public int _age;}- (void)test; // 对象方法+ (void)test; // 类方法@end@implementation Person- (void)test{ NSLog(@"123");}+ (void)test{ //NSLog(@"%d",_age);这种写法不对,是因为age是一个实例变量,那么也就是说,它只能用对象方法来调用,类中是没有对应的成员变量的 NSLog(@"345");}@endint main(){ Person *p = [Person new]; p->_age = 20; [p test]; [Person test]; return 0;}
何时使用类方法:
#import <Foundation/Foundation.h>@interface Jisuanqi : NSObject+ (int)sumofNum1:(int)Num1 andNum2:(int)Num2;+ (int)averofNum1:(int)Num1 andNum2:(int)Num2;@end@implementation Jisuanqi+ (int)sumofNum1:(int)Num1 andNum2:(int)Num2{ return Num1 + Num2;}+ (int)averofNum1:(int)Num1 andNum2:(int)Num2{ int a = [Jisuanqi sumofNum1:(int)Num1 andNum2:(int)Num2]; return a/2;}@endint main(){ int i = [Jisuanqi sumofNum1:10 andNum2:12]; int j = [Jisuanqi averofNum1:12 andNum2:20]; NSLog(@"sum=%d,aver=%d",i,j);}
- 黑马程序员--06OC类和对象
- 黑马程序员-OC语言类和对象
- 黑马程序员-ios学习笔记 oc 类和对象
- 黑马程序员---OC类和对象
- 黑马程序员--OC类和对象
- 黑马程序员-OC语言-类和对象
- 黑马程序员---OC基础---类和对象
- 黑马程序员------OC 对象和类
- 黑马程序员--oc语言类和对象
- 黑马程序员--ios基础--oc语言--类和对象
- 黑马程序员-OC——类和对象
- 黑马程序员——OC类和对象
- 黑马程序员——OC——类和对象
- 黑马程序员——OC语言中的类和对象
- 黑马程序员——OC中类和对象
- 黑马程序员-OC学习笔记-----类和对象
- 黑马程序员——OC-4:类和对象
- 黑马程序员--IOS学习日记:02--OC类和对象
- Think in Java(十四):容器深入研究
- IOS 七种手势详解(动图+Demo下载)
- leetcode Valid Parentheses
- [BZOJ 1064][NOI 2008]假面舞会(图论+BFS)
- Cocos2d-x 3.2 onEnter与onEnterTransitionDidFinish的区别
- 黑马程序员--06OC类和对象
- poj 1330 Nearest Common Ancestors
- Codeforces 337E Divisor Tree 暴搜
- BZOJ 3833 [POI 2014] Solar Lamps 解题报告
- Java并发的四种风味:Thread、Executor、ForkJoin和Actor
- ECMAScript的数据类型(1)
- Smarty----注册一个函数以plugins方式
- Https握手(验证证书->交换密钥) 证书防伪造(签名验证), 防篡改(签名验证),防替换(域名验证),防假冒(解不开密钥)
- 数据库中如何写视图,以及视图项目中实际应用