黑马程序员——6、OC语言(基本语法)
来源:互联网 发布:判断素数的条件c语言 编辑:程序博客网 时间:2024/05/02 02:46
---------------------- Java培训、Android培训、iOS培训、.Net培训,期待与您交流! ---------------------
一、OC的简单认识
1. OC与C
OC是全称Object-C,是在C语言的基础上增加了一层最小的面向对象语法。
OC完全兼容C语言,可以在OC代码中混入C语言代码,甚至C++代码。
OC可以用来开发Mac OS X平台和IOS平台的应用程序。
2. OC关键字
OC的关键字基本上都是以@开头的:
@interface、@implementation、@end
@public、@protected、@private、@selector
@try、@catch、@throw、@finally
@protocol、@optional、@required、@class
@property、@synthesize、@dynamic
self、super、id、_cmd、__block、__strong、__weak
OC中的字符串也都是@“字符串”的形式。
3. 数据类型
基本数据类型:
C语言的基本数据类型适用于OC中,如字符型char、整型int、浮点型float/double等等
但是OC类型多了一个布尔型数据类型:BOOL(YES/NO)。
BOOL b1 = YES; BOOL b2 = NO; BOOL b3 = 1; //YES BOOL b4 = 0; //NO
</pre><h2><span style="font-family:SimHei;font-size:18px;font-weight: normal;"> 4. OC的简单使用</span></h2><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><span style="font-family:SimSun;font-size:12px;">(1)跟C语言一样,OC程序的入口函数依然是main函数。OC源程序被写到了一个.m文件中。</span></p></blockquote><p></p><pre name="code" class="objc">//OC程序的入口:main函数int main(){ return 0;}
(2)OC程序运行过程:
1》编写OC源程序:.m .c
2》编译:cc -c xxx.m xxx.c
3》链接:cc xxx.o xx.o -framework Foundation(只有用到Foundation框架才需要引入)
4》运行:./a.out
(3)Foundation框架头文件的路径
1》右击Xcode.app --> 显示包内容
2》Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/Foundation.framework
Xcode模板修改路径:
/Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates
* File Templates文件模板:可以修改类文件等
* Project Templates 项目模板:可以修改一些项目描述
(4)Foundation框架
#import <Foundation/Foundation.h>
只需要包含Foundation框架的主头文件,就可以使用整个框架的东西。
#import的用途:
1》跟#include一样,拷贝文件的内容。
2》可以自动防止文件的内容被重复拷贝。
不需要在头文件中加入下面的预处理指令:
#ifndef _STDIO_H_
#define _STDIO_H_
函数声明等操作
#endif
(5)NSLog和printf的区别
1》NSLog接收OC字符串作为参数,printf接受C语言字符串作为参数。
2》NSLog输出后会自动换行,printf输出后不会自动换行。
3》使用NSLog需要#import <Foundation/Foundation.h>,使用printf需要#include <stdio.h>。
(6)布尔型BOOL
BOOL的本质:typedef signed char BOOL;
BOOL变量的取值:YES/NO
#define YES (BOOL)1
#define NO (BOOL)0
由BOOL变量的取值可以看出,BOOL变量可以当做整数1、0来使用。
二、OC的面向对象
1. 面向对象思想
C是面向过程的,OC是面向对象的。
1》面向过程与面向对象的区别
面向过程关注的时解决问题需要哪些步骤;面向对象关注的时解决问题需要哪些对象。
2》术语
面向过程:Procedure Oriented
面向对象:Object Oriented,简称OO
面向对象编程:Object Oriented Programming ,简称OOP
2. 类和对象
(1)类的设计
1》类名
* 类名的第一个字母必须大写
* 不能有下划线
* 多个英文单词,用驼峰标识
* 一般名词都是类
2》属性
* 拥有相同属性和行为的对象都可以抽象出一个类
3》行为(功能)
* 谁最清楚这个行为,这个行为就应该在哪个类中,该交给谁执行这个行为,由该类决定
(2)类的声明
用来声明对象的属性和行为。
成员变量和方法不能用static等关键字修饰,不能跟C语言的函数或变量混淆。
</pre><pre name="code" class="objc">#import <Foundation/Foundation.h>//: NSObject 目的是让Car这个类具备创建对象的能力@interface Car : NSObject{//大括号,用来声明对象属性 //成员变量(实例变量),默认初始化为0(成员变量不能在这里进行初始化操作) //@public 可以让外部的指针间接访问对象内部的成员变量 @public int wheels; int speed;}//方法(行为)(方法也分声明和实现两步)//方法名、参数、返回值//只要是OC对象的方法,必须以减号- 开头//OC方法中,任何数据类型都必须用小括号()括住//OC方法中,小括号就一个作用:括住数据类型- (void)run;@end
</pre></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><div><h3><span style="font-family:SimHei;font-size:14px;font-weight: normal;">(3)类的实现</span></h3></div></blockquote><div><pre name="code" class="objc">//方法的实现(说清楚方法里面的功能)@implementation Car- (void)run{ NSLog(@"车子跑起来了!");}@end
(4)创建对象
* 在使用类创建对象之前,系统会先将类加载到内存中;
* 在类中,成员变量是对象独有的,而方法是对象共有的。
//利用类来创建对象 //在OC中,想执行一些行为,就应该写上一个中括号[行为执行者 行为名称] // [Car new];//执行了Car这个类的new行为来创建新对象 //定义一个指针变量p,p将来指向的是Car类型的对象 //[Car new]每次都会创建一个新的对象,并且会返回新对象本身(新对象的地址) Car *p = [Car new]; //给p所指向的对象的属性赋值 p->wheels = 4; p->speed = 120; Car *p2 = [Car new]; p2->wheels = 5; p2->speed = 210; //给p所指向的对象发送一条run消息 [p run];
(5)对象与函数
1》对象成员变量作为函数参数:是值传递,传递到函数的只是对象成员变量的值。在函数里改变这个值并不会影响外界对象的值。
2》指向对象的指针作为函数参数:是地址传递,传递到函数的是指向对象的指针。如果在函数里对这个指针指向的对象的值进行了改变,外界的对象的值也将随之改变。
void test(int w, int s){ w = 20; s = 200;}void test2(Car *newC){ newC->wheels = 5;}void test3(Car *newC){ Car *c2 = [Car new]; c2->wheels = 5; c2->speed = 300; newC = c2;//指针指向变了 newC->wheels = 6;}int main(){ Car *c = [Car new]; c->wheels = 4; c->speed = 120; test(c->wheels, c->speed); // 值传递 test2(c); // 地址传递 test3(c); // 地址传递 return 0;}
(6)匿名对象
//不要写类似匿名对象这样的代码,会造成内存泄露 [Car new]->speed = 300; [[Car new] run];//每次[Car new]都会创建新对象。。
3. 方法
(1)OC方法与函数
方法:
1》对象方法都是以减号- 开头
2》对象方法的声明必须写在@interface和@end之间,对象方法的实现必须写在@implementation和@end之间
3》对象方法只能由对象来调用
4》对象方法归类和对象所有
函数:
1》函数能写在文件的任意位置(@interface和@end除外),函数归文件所有
2》函数调用不依赖于对象
3》函数内部不能直接通过成员变量名访问某个成员变量
(2)OC方法的使用注意
* 方法只有声明,没有实现(程序崩溃:闪退(运行过程中出错) 运行错误:unrecognized selector sent to instance 0x7fdcab409690)
* 方法没有声明,只有实现(编译器警告,但是能调用,这是OC的弱语法)
* OC在运行过程中才会检测有没有相应的方法。
* 编译的时候:如果访问了不存在的成员变量则直接报错;如果访问了不存在的方法,仅仅只是警告。
* 冒号也是方法名的一部分。
* 同一个类中不允许有两个对象方法同名。
#import <Foundation/Foundation.h>@interface JiSuanQi : NSObject//方法名:pi- (double)pi;//OC方法中,一个参数对应一个冒号//方法名:pingFang:(冒号也是方法名的一部分)- (int)pingFang:(int)num;//- (int)sum:(int)num1 :(int)num2;//方法名:sumWithNum1:andNum2:- (int)sumWithNum1:(int)num1 andNum2:(int)num2;//- (int)sumWithNum1:(int)num1 andNum2:(int)num2 andNum3:(int)num3;@end@implementation JiSuanQi- (double)pi{ return 3.14;}- (int)pingFang:(int)num{ return num*num;}//- (int)sum:(int)num1 :(int)num2- (int)sumWithNum1:(int)num1 andNum2:(int)num2{ return num1+num2;}@end
(3)方法的分类
类方法和对象方法可以同名。
1》类方法
格式:[类名 方法名];
* 以加号+ 开头;
* 只能用类名调用,对象不能调用;
* 类方法中不能访问实例变量(成员变量);
好处:不依赖于对象,执行效率高。
使用场合:当方法内部不需要使用到成员变量时,就可以改为类方法。
2》对象方法
格式:[对象名 方法名];
* 以减号- 开头;
* 只能让对象调用,没有对象,这个方法就不可能被执行;
* 对象方法能访问实例变量(成员变量)。
#import <Foundation/Foundation.h>@interface Person : NSObject{ int age;}+ (void)printClassName;- (void)test;+ (void)test;@end@implementation Person+ (void)printClassName{ //实例变量age不能再类方法中访问 //NSLog(@"this class call Person = %d", age); NSLog(@"this class call Person");}- (void)test{ NSLog(@"test对象方法"); [Person test];}+ (void)test{ NSLog(@"test类方法"); //死循环 //[Person test];}@endint main(){ //用对象调用类方法,运行报错,不能识别。。 Person *p = [Person new]; [p test]; [Person test]; [Person printClassName]; return 0;}
(4)setter方法和getter方法
一般为了防止使用@public对对象的成员随意赋值,我们使用setter方法和getter方法来管理成员的访问。
1》setter方法
* 作用:给外界提供一个方法用来设置成员变量,可以在方法里面过滤掉一些不合理的值
* 命名规范:
方法都是以set开头,而且后面跟上成员变量名,成员变量名的首字母必须大写;
返回值一定是void,一定要接受一个参数,而且参数类型跟成员变量类型一致;
形参名称不要跟成员变量同名。
2》getter方法
* 作用:返回对象内部的成员变量
* 命名规范:
肯定有返回值,而且类型跟成员变量一致;
不需要接收任何参数;
getter方法的名称一般就跟成员变量同名。
3》成员变量的命名规范
* 成员变量都以下划线_ 开头;
* 可以跟get方法的名称区分开;
* 可以跟其他局部变量区分开,一看到下划线开头的变量,一般都是成员变量。
4. self关键字
当成员变量和局部变量同名时,系统就会采取就近原则,访问局部变量,而不是访问成员变量。这时,我们可以用self访问成员变量,区分同名的局部变量。
概念:谁调用了当前方法,self就代表谁(方法调用者)
* self出现在对象方法中,self代表对象
* self出现在类方法中,self代表类
格式:
1》self->成员变量名:访问当前方法调用的成员变量
2》[self 方法名]:调用方法(对象方法或类方法)
使用场合:所有的OC方法中,包括对象方法和类方法,不能出现在函数中。
-(void)test{ // self死循环【注意】 //self是个指针,指向方法调用者,代表当前对象 [self test]; }
三、OC面向对象的三大特征
1. 封装
2. 继承* readonly:只读,只提供getter方法就行。
* 成员变量:一定要以下划线_ 开头
作用:让成员变量与get方法名区分开;可以跟局部变量区分开。
成员变量尽量不要用@public,以便更好地实现封装。
封装的好处:
1》更加接近人类的思考方式,只需要关注对象和行为,不需要关注具体实现步骤。
2》过滤不合理的值,屏蔽内部的处理过程,让外界不需要关注内容的细节。
* 直接调用父类中的某个方法。
* super处在对象方法中,那么就会调用父类的对象方法;super处在类方法中,那么就会调用父类的类方法。
* 使用场合:子类重写父类的方法时,想保留父类的某些做法。
* 将具有相同属性和行为的类,抽取出一个父类;
* 子类在父类的基础上,再扩充属性和方法;
* 子类的方法和属性的访问过程:先去子类里面找,如果子类没有,再去父类里面找;
* 父类被继承了,但是还是可以照常使用这个类;
* 全部OC类的最终父类是NSObject。
专业术语:父类/超类 superclass、子类 subclass/subclasses
(1)继承的好处和坏处
好处:不改变原来模型的基础上,扩充方法;建立了类与类之间的联系;抽取了公共的代码,减少代码编写;子类可以拥有父类的所有成员变量和方法。
坏处:耦合性强,类之间的关系太紧密(改一类而动很多类)。
(2)继承的使用场合
* 当两个类拥有相同的属性和方法的时候,就可以将相同的东西抽取到一个父类中;
* 当A类完全拥有B类中部分属性和方法时,可以考虑让B类继承A类,或考虑B类组合A类。
(3)继承的注意事项
* 继承是单继承,不能继承自多个类;
* 父类必须声明在子类前面;
* 子类和父类不能有相同的成员变量;
* 子类可以重写父类的方法,调用某个对象的方法时,优先区当前对象的类中寻找,之后才会往父类方向找。
(4)super
格式:[super 方法名];
super的作用:
(5)继承和组合
继承:xxx 是 xx
组合:xxx 拥有 xx
#import <Foundation/Foundation.h>/*************Animal声明****************/@interface Animal : NSObject{ int _age; double _weight;}- (void)setAge:(int)age;- (int)age;- (void)setWeight:(double)weight;- (double)weight;@end/*************Animal实现****************/@implementation Animal- (void)setAge:(int)age{ _age = age;}- (int)age{ return _age;}- (void)setWeight:(double)weight{ _weight = weight;}- (double)weight{ return _weight;}@end/*************Dog声明****************///: Animal 代表继承了Animal,相当于拥有了Animal里面的所有成员变量和方法//Animal称为Dog的父类//Dog称为Animal的子类@interface Dog : Animal@end/*************Dog实现****************/@implementation Dog@end/*************Cat声明****************/@interface Cat : Animal@end/*************Cat实现****************/@implementation Cat@end
3. 多态
概念:某一类事物的多种形态。
(1)多态的实现
* 没有继承就没有多态。
* 子类对象赋值给父类的指针,然后用父类指针就可以访问子类对象的属性和方法了。
* 多态是动态绑定,即在运行时,根据对象的具体类型来确定动态调用的方法是哪个子类(或父类本身)的方法。
(2)多态的好处和坏处
好处:如果函数、方法参数中使用的时父类类型的,可以传入父类、子类对象。
坏处:不能访问子类的属性(成员变量),不能调用子类特有的方法(子类有父类没有的方法)(除非强制类型转换)
#import <Foundation/Foundation.h>//Animal@interface Animal : NSObject- (void)eat;@end@implementation Animal- (void)eat{ NSLog(@"Animal eating..");}@end//Dog@interface Dog : Animal- (void)run;@end@implementation Dog- (void)eat{ NSLog(@"Dog eating..");}- (void)run{ NSLog(@"Dog running");}@end//Cat@interface Cat : Animal@end@implementation Cat- (void)eat{ NSLog(@"Cat eating..");}@end//如果形参中使用的时父类类型,可以传入父类对象、子类对象void feed(Animal *a){ [a eat];}int main(){ /* //多种形态 Dog *d = [Dog new]; //Dog类型 //多态:父类指针指向子类 Animal *a = [Dog new]; [a eat]; //调用方法时 会检测对象的真实形象 // 只是警告,弱语法// Cat *c = [Animal new];// NSSring *s = [Cat new]; */ Dog *d = [Dog new]; feed(d); Cat *c = [Cat new]; feed(c); //多态的局限性:父类类型的指针变量,不能用来调用子类的方法 [aa run]; //虽然只是警告(编译器),运行时动态检测(所以运行通过) Animal *aa = [Dog new]; //[aa run]; // 错误 Dog *dd = (Dog *)aa; //强制转换就好了,(Dog *)类型转换是给编译器看的 [dd run]; // 正确 return 0;}
- 黑马程序员——6、OC语言(基本语法)
- 黑马程序员——OC语言(一)--基本语法
- 黑马程序员——OC语言基本语法
- 黑马程序员——OC语言------基本语法
- 黑马程序员——OC语言基础篇---基本语法、类
- 黑马程序员——OC---初接触及基本语法
- 黑马程序员——01OC的基本语法
- 黑马程序员:OC基本语法
- 黑马程序员-OC基本语法
- 黑马程序员--OC基本语法
- 黑马程序员——OC语言——点语法
- 黑马程序员——OC语言核心语法
- 黑马程序员——OC语言基础篇---核心语法
- 黑马程序员—OC语言基础—基础语法知识
- 黑马程序员—OC语言基础—核心语法小结
- 黑马程序员 -- OC语言 基本语法 类 对象
- 黑马程序员-OC笔记(一) OC基本语法
- 黑马程序员——OC语言加强---autorelease基本使用
- Java 工厂模式简单运用
- sed 用法
- @MappedSuperclass
- Oracle自带的用户
- Leetcode:Longest Valid Parentheses
- 黑马程序员——6、OC语言(基本语法)
- 转载将多个工程打包成一个apk
- Dex文件的内存映射
- 使用QUdpSocket进行UDP编程
- android学习笔记之说说drawable目录下的xml
- 项目组成员工作积极性变高了
- Bootstrap 自定义分页方法
- Java异常
- UVA 348 - Optimal Array Multiplication Sequence