iOS OC语言(一)语法简介 , OC 的特点
2015-11-05 09:26
357 查看
前言
OC是对C语言的扩充C语言的弊端:维护升级十分复杂
面向对象的特点:封装 继承 多态
什么是对象:万物皆对象
OC的特点
1.是C语言的超集, 允许在OC中使用C语言的源代码. 编译器兼容C语言程序
2.具备完善的面向对象特性3.包含一个运行时系统
4.类库丰富(指开发人员写的类库)
分析对象是最重要的一环, 是保证程序的扩展性 健壮性 最重要的一步.面向对象编程设计:
分析涉及到的对象
根据功能定义类
使用对象的功能完成程序
类是抽象的, 对象是具体的
类 是具有相同特征和行为的事物的抽象
对象是类的实例
类是对象的类型
万事万物皆对象
用类创建对象叫 用类实例出一个对象
创建对象分两个过程
1. 分配内存空间 (在堆区开辟空间 需要管理的, 保存的是对象的实例变量和方法) alloc
2. 对对象进行初始化 (给对象的值进行默认赋值: 默认赋值为0) init
OC语法
OC的输出方法: NSLog(@"OC是一门面向对象的语言");
NSLog相比printf
自带\n 换行功能
@符号 是OC关键字的标志
NSObject 是OC中所有类的基类
OC常用数据类型:
整型: NSInteger (64位下为long, 否则是int)
浮点型: CGFloat (double的别名)
字符串型: NSString
NSString *str = @“这是一个OC对象”;
如果声明变量的时候有* 表示这是一个对象
输出字符串:
NSLog(@"%@", str);
%@ 占位符, 可以输出所有对象(换言之: 只要是对象 都可以用%@占位符)
NSInteger 占位符为 %ld
CGFloat 占位符为%f
OC类中的方法 是根据使用方式命名的, - 修饰的方法是对象调用的方法, + 修饰的方法是类调用的方法
调用- 修饰的方法 需要用类创建一个对象, 再用创建好的对象来调用该方法
调用+ 修饰的方法 可以直接使用类名来调用
OC当中调用方法 使用中括号来调用
p.s. 方法和函数的区别: 函数是随时随地可以随意调用, 方法必须依托于一个对象或者类才能调用
实例化对象的语法:
类名 *对象名 = [[类名 alloc] init];
如:
Person *p = [[Person alloc] init];
或者分步写成
<span style="font-size:18px;"><code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">Person *p = [Person alloc]; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 分配空间</span> [p init]; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 对对象初始化</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul></span>
另一种实例化方法:
Person *p1 = [Person new];// 开辟空间并初始化, 但此方法通常不用 因为它可以初始化, 但没法指定初始化内容
而用第一种方法可以重写init方法, 对对象初始化指定数据
给实例变量赋值 (给对象赋值)
表明实例变量的关键字:
@public // 表示在类外可见, 被@public 修饰的实例变量, 可以在类外部赋值
@private // 表示仅在本类内可见, 被@private 修饰的实例变量, 只能在类内赋值
@protected // 可以被子类继承, 但不能在类外直接赋值.
对于用关键字@public 修饰的成员变量而言, 可以在主函数中赋值. 语句如下:
<span style="font-size:18px;"><code class="hljs haskell has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-title" style="box-sizing: border-box;">p</span> ->_name = @<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"小明"</span>; <span class="hljs-title" style="box-sizing: border-box;">p</span> ->_sex = @<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"男"</span>; <span class="hljs-title" style="box-sizing: border-box;">p</span> ->_age = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">21</span>; <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">NSLog</span>(@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"姓名: %@ 性别: %@ 年龄:%ld"</span>, p->_name, p->_sex, p->_age);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul></span>
上述写法和C语言中的结构体变量赋值十分类似, 事实上可以理解为类即使结构体的加强版, 功能上比结构体扩充了非常多. 类不止有成员变量的类型得到了扩充, 可以定义成员变量的可见度. 且可以在类中声明方法, 这些是结构体远远不能相比的特性. 另外, 在OC中一般不说指针, 而是称其为某个类的对象. 但是通过指向符给成员变量赋值的原理和结构体变量给成员变量赋值的原理相似.
OC创建类格式
<span style="font-size:18px;"><code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// .h是接口文件</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@interface</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Person</span>(类名) : <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">NSObject</span> ((继承自)父类)</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 中间写声明 或者 实例变量(特征) 行为的声明</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 声明变量(特征)方式: 需添加一个{}, 在{}里面声明实例变量</span> { <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *_name; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 命名规范 只要是类的特征, 实例变量名字前要加上一个”_"</span> } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 在{}外面写行为(方法)</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// void sayHi(); C语言声明函数的方式</span> - (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)sayHi; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// OC中声明方法时在前面加上-, ( - 方法, 也叫实例方法或者对象方法)</span> + (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)walk; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 声明方法时在前面加上+ ( + 方法, 也叫类方法)</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@end</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 声明接口的结束部分</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// .m是实现文件</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@implementation</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Person</span> (类名)</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 中间写行为(方法)的实现部分</span> - (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)sayHi{ <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSLog</span>(@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"hello"</span>); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@end</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// p.s 括号内的中文为注释, 完整代码参照中文移除括号及其内的中文后即可</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li></ul></span>
重写初始化方法:
重写初始化方法 重写的是父类的方法; 重写的话 一定要跟父类的方法 名字一样 返回值一样, 参数一样 只有实现内容不一样.
id instancetype 的区别:
instancetype 表示返回一个对象类型 相当于C语言里的 void* 无类型指针 (可以转化成任何类型的指针)
id 表示一个对象类型 功能和instancetype相似, 一样可以返回一个任意类型的对象.
但是可以用id来声明一个对象, 而instancetype只能做返回值类型, 不能用来声明对象
一般重写的初始化方法写在最上面
<span style="font-size:18px;"><code class="hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">- (instancetype)init; <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 在.h文件中声明 - (instancetype)init { <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 在.m文件中实现 <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> = [<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span> init]; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>) { _name = @<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"小明"</span>; _sex = @<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"男"</span>; _age = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">21</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>; <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>代表本类的对象 }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul></span>
self和super
self在本类中, 表示本类的对象
super 表示父类的对象
但是值得注意的是: 这么写(重写父类的初始化方法)会导致每个新建的对象的初值全都相同. 所以通常建议使用自定义初始化方法, 而不是重写父类的初始化方法.
自定义初始化方法:
<span style="font-size:18px;"><code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">- (instancetype)initWithName:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *)name <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 在.h文件中声明自定义初始化方法</span> sex:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *)sex age:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSInteger</span>)age; - (instancetype)initWithName:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *)name <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 在.m文件中实现自定义方法</span> sex:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *)sex age:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSInteger</span>)age{ _name = name; _ a517 sex = sex; _age = age; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul></span>
p.s. instancetype 相当于 (类名*) 由于类名是每个类都不同的 就用instancetype代替, 简化思路. 另外上面的自定义初始化方法的写法是不完整的. 完整的写法参照重写自定义方法.
相关文章推荐
- C语言中的字符变量和字符常量
- C语言中的"NULL"到底是什么?又不是什么?有什么用?怎么用?
- static和const的应用和作用
- [转载]常量指针与指针常量的区别
- [转载]C++中的四种类型转换方式
- [转载]C++中sizeof的使用总结
- C/C++高阶语法:引用
- C/C++语言中关于const用法的总结
- 2013年华为c语言上机试题3
- C++设计模式-Adapter适配器模式
- c++中的强制转换static_cast、dynamic_cast、reinterpret_cast的不同用法儿
- 一维数组的函数调用
- C++设计模式-Singleton
- C++中基类私有成员会被继承吗
- C++中基类私有成员会被继承吗
- C++设计模式-Observer观察者模式
- C++ 二叉树 叶子节点
- C++string类型成员函数实现
- C++,二叉树,叶子节点
- C++ Primer中文版(第五版)——第六章 函数