在Objective-C中浅谈面向对象
接触面向对象也有一段时间了,当时是通过C++学习的OOP,后来又接触到了PHP和Java。每种OOP的语言在面向对象上或多或少都会有不同的地方,现在在学习OC的面向对象部分,又感觉到OC面向对象的特点。写篇博文总结一下OC中的面向对象。刚接触OC,用OC中的便利初始化方法和便利构造器有点蹩脚,不过还可以在接受的范围之内,以下的东西可能会对面向对象的特征:抽象,封装,继承等总结的较少一些,主要总结了OC中面向对象的特点。在用到便利构造器的时候,如果之前学习过设计模式的话会好理解一些。
在下面的代码实例当中,可能在便利初始化方法和便利构造器这一块理解起来有些问题。简单的说来,便利构造器是为了简化对象的初始化而生的,在之前的博客中也说了一嘴:编程是间接的过程,其实使用便利构造器就是间接的过程。在程序中处处都用到了间接。比如你定义的变量,你定义的函数,都是在间接的使用一些东西。在现实生活中间接的作用的很大的,就连找个女朋友也要间接一下,如果间接好了你很有可能和奥巴马成为好哥们不是吗,不是有种理论叫做六度人脉吗?程序中的间接的好处是什么呢?
根据个人的理解,间接原则会让自己写的代码更为灵活,会避免一些不必要的重复编写代码。函数就是一个最好的例子,把程序中不变且常用的部分进行封装,然后把变的部分用函数的参数列表传进来,这样就很好的实现代码的重用功能,这也是函数存在编程中的意义所在。伪文艺一下,哲学上不是有句话叫做世界上每种存在的事物都有他存在的意义。达尔文的适者生存论放在计算机技术发展中也是挺适用的,能被保留的东西一定会有他的作用。
言归正传,便利构造器就是对便利初始化函数的间接使用,目的是为了简化对象的初始化(这里是我个人的理解)。便利初始化函数(对象方法)的作用是给实例常量赋初值,在类的实例化后就可以调用便利初始化函数了。而便利构造器是类方法,返回的是对象,在便利构造器中做了两件事:一个是给对象分配空间,第二个是调用便利初始化函数进行数据的初始化。学过设计模式的小伙伴都应该知道“模板方法模式”,我个人感觉便利构造器和模板方法模式的作用挺相似的。
以下的东西是依附于代码来讲解的,编程吗,即使讲思想也少不了代码不是吗,话不多说,切入正题。请大家批评指正,若要转载请注明出处。
面向对象程序开发的主要目标:用代码模拟现实中的对象,将现实中对象的某些行为能力,特征用代码表现出来,然后用这些代码来模拟现实中的问题。
每个对象都会从两个角度进行描述,一个是特征,一个是行为能力
特征:可以是物体的组成部分,也可以是一些物理或逻辑上的属性,用来表现对象的形态,构成及状态。
行为能力:对象所能被进行的操作或者物体本身发起的操作。用来接受外部操作或对外部进行操作。
封装:将属性及方法相结合,共同体现对象的特征,称之为封装,封装可以实现隐藏内部实现,稳定外部接口。
在OC中类是由接口(interface)和实现(implementation)两部分构成的。在OC中类是通过两个单独的文件定义。接口定义在对应的头文件中,该文件的作用是说明此类具有哪些属性和方法,但不去实现其行为。
1. OC中接口的定义如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#import <Foundation/Foundation.h>@interface Student : NSObject{//大括号里定义属性 //定义学生的学号,姓名,年龄,爱好; @public NSString *studentName; int age; NSString *hobby;}/*定义学生有关的方法,+修饰的为类方法,不用实例化就可以直接用类访问* -号修饰的为对象方法,必须实例化后才能使用,就是用对象调用的方法*///定义打招呼的方法- (void) sayHello;//吃饭行为- (void) eat;@end |
代码说明:
1.#import<Foundation/Foundation.h>语句告诉编译器查看Foundation框架中的Foundation.h的头文件
2.用#import指令来导入相应的文件,#import的作用相当于PHP中的require_once,如果文件之前导入过了,则不导入,而#include会重复导入文件的
3.用编译器指令@interface来定义类的声明,@interface后面是类名,Student : NSObject 说明Student继承于NSObject类
4.在接口中方法只有声明,没有实现,方法前面的减号代表此方法是对象方法,如果是+号的话,说明是类方法,就是说类可以直接访问此方法。
5.@interface 和 @end是成对出现的,@end代表接口定义的结束
6.上面得成员变量定义成了公有的,这在开发中是极少见的,这里为了方便练习才这么写的,一般把成员变量定义为私有的然后在定义get,set方法去操作成员变量
这样才起到了封装,不要把自己的手直接伸入到类中,要通过类提供的方法来操作类的成员变量。
2.@implementation 实现部分
实现部分文件的扩展名为.m,具体实现的方法代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#import "Student.h"@implementation Student//实现打招呼的行为- (void) sayHello{ NSLog(@"hello! 我是%@, 我今年%d岁了, 我喜欢%@!", studentName, age, hobby);}//实现吃饭行为- (void) eat{ NSLog(@"%@也得吃饭呢!",studentName);}@end |
代码说明:
1.在实现文件中首先导入对应的类的接口文件#import "Student.h",引入系统文件用<FileName>, 引入自定义文件用“FileName”;
2.用编译器指令@implementation来声明类方法的实现
3.@implementation和@end也是成对出现的
代码规范:
1.类名的首字母要大写
2.方法的命名使用驼峰命名法
3.创建和使用对象
定义了一个类,一般需要实例化才能使用,当然静态类是不需要实例化就能用的。对象是类的实体,类是对象的抽象,因此需要对类进行实例化。
实例化的代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#import <Foundation/Foundation.h>//引入定义的类#import "Student.h"int main(int argc, const char * argv[]){ @autoreleasepool { //创建对象,完成对象的声明,内存分配,初始化 Student *student = [[Student alloc] init]; //为了方便,在这就直接给成员变量赋值,前提是成员变量是公有的 student->studentName = @"ludashi"; student->age = 20; student->hobby=@"爱咋咋地"; //调用成员方法 [student sayHello]; [student eat]; } return 0;} |
代码说明:
1.要在一个类中实例化类,首先要引入类的接口定义文件如上面的 #import “Student.h”;
2.OC中类的实例化方式是 Student *student = [[Student alloc] init], 可以理解为Student类在NSObject类中继承了alloc方法, alloc这个方法是用来
实例化对象的 init 是默认的构造方法
3.在OC中对象调用其中的方法是通过[]来实现的,[对象名 方法名];
定义对象的语法:
类名 *对象名 = [ [ 类名 alloc ] init ]; 或者
类名 *对象名 = [ 类名 new];
给对象的成员变量赋值和调用对象的方法如下:
对象名->成员变量名 = 具体值;
[ 对象名 方法名];
一:类方法和对象方法
上面也提到了,减号开头的方法为对象方法,需要实例化类后通过对象来进行调用。对象方法允许调用对象方法和对象变量加号开头的方法为类方法,通过类就可以直接调用的方法。
下面是一些方法调用的一些规则:
1.类方法可以调用类方法;
2.类方法不可以调用对象方法;
3.类方法不可以使用对象变量,类方法可以使用self(self相当于java中的this);
4.可以通过类来调用类方法,但对象不可以调用类方法
1.对象的初始化
可以重写父类中的方法init来进行对象的初始化,就相当于Java中的构造函数,重写代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
|
//重写init方法,为本类添加构造方法-(id) init{ if (self =[super init]) { studentName = @"dashi"; age = 18; hobby = @"hehe"; } return self;} |
代码说明:
1.因为init是继承过来的方法因此不需要在interface里面声明,直接在implementation中进行重写就OK了;
2. init的返回类型为id, id是OC中的一切父类.在面向对象中父类可以声明子类的变量
3.[super init]是为了初始化父类的成员变量,返回值为子类对象,如果返回nil,说明父类没有alloc成功,即不能在alloc子类对象。
2.便利初始化函数
自定义的便利初始化函数的作用是让用户自己初始化用户所实例化的对象,便利初始化函数以init开头,我们可以在类中自定义便利初始化函数。因为便利初始化函数是自 己。 定义的所以需要在@interface中进行声明,便利初始化函数可以进行重载
在@implementation中进行重新的代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
//实现便利初始化方法1- (id) initWithName:(NSString *)sName iAge:(int)anAge{ if (self = [super init]) { studentName = [sName copy]; age = anAge; } return self;}//实现便利初始化方法2- (id) initWithName:(NSString *)sName{ if (self = [super init]) { studentName = [sName copy]; } return self;} |
代码说明:
1.函数名后面的冒号跟的是参数列表,在OC中定义参数的方式是: (参数类型)参数名 第二个参数别名:(参数类型)参数名
使用便利初始化方法来进行对象的初始化,代码如下:
|
1
2
3
|
//调用便利初始化方法Student *s1 = [[Student alloc] initWithName:@"dashi1" iAge:19];[s1 sayHello]; |
3.便利构造器
上面用便利初始化方法在类实例化时有些繁琐,为了简化实例化的操作,自定义一个类方法,类方法的作用是进行类的实例化同时进行参数的初始化,并返回对象
便利构造器的实现代码如下:
|
1
2
3
4
5
6
|
//实现便利构造器,进行类的实例化并调用initWithName+ (id) studentWithName:(NSString *)name age:(int)sAge{ Student *student = [[Student alloc] initWithName:name iAge:sAge]; return student;} |
便利构造器的使用如下:
|
1
2
|
//调用便利构造器初始化对象Student *s2 = [Student studentWithName:@"dashi2" age:20]; |
在Objective-C中浅谈面向对象的更多相关文章
- python进阶_浅谈面向对象进阶
python进阶_浅谈面向对象进阶 学了面向对象三大特性继承,多态,封装.今天我们看看面向对象的一些进阶内容,反射和一些类的内置函数. 一.isinstance和issubclass class F ...
- IOS中 浅谈iOS中MVVM的架构设计与团队协作
今天写这篇文章是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇文章的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...
- 你真的懂Flask中浅谈蓝图Blueprint吗?
一,什么是Flask中的蓝图Blueprint Blueprint是用于实现Flask框架中单个应用的视图,模板,静态文件的集合. Blueprint 是一个存储操作(路由映射)方法的容器,这些操作在 ...
- .NET项目开发—浅谈面向对象的纵横向关系、多态入口,单元测试(项目小结)
阅读目录: 1.开篇介绍 2.使用委托消除函数串联调用 2.1.使用委托工厂转换两个独立层面的对象 3.多态入口(面向对象继承体系是可被扩展的) 4.多态的受保护方法的单元测试(Protected成员 ...
- Java系列1 -- 浅谈面向对象
也许每一个计算机专业的人,在大学学习java的时候,老师开始时都会说这么一句话,"Java是一门面向对象的语言".那么面向对象到底是什么,他有什么好处,或者他比其他流行的语言C/C ...
- day10 浅谈面向对象编程
面向对象编程:第一步找名词,名词是问题域中的. 第二步概括名词设计成类.某些名词可以浓缩包含到其它名词中,成为其属性. 第三步找动词,动词也是问题域中的. 第四步概括动词设计成方法.动作的产生往往 ...
- Python之浅谈面向对象
目录 面向对象和面向过程 面向过程 面向对象 类与对象 定义类 在现实世界中:先有对象,再有类 在程序中,务必保证:先定义(类),后使用(产生对象) 产生对象 类 对象 产生对象 属性查找顺序 对象赋 ...
- 从一次异常中浅谈Hibernate的flush机制
摘自http://www.niwozhi.net/demo_c70_i1482.html http://blog.itpub.net/1586/viewspace-829613/ 这是在一次事务提交时 ...
- 在java中浅谈Math类中的常用方法
通过最近的学习,学到了一些的Math类中的常见方法 package org.stm.demo; public class Test { public static void main(String[] ...
随机推荐
- CentOS 简单设置samba服务
1.安装 yum -y install samba 2.设置配置文件 1) 备份Samba的配置文件:cp /etc/samba/smb.conf /etc/samba/smb.conf.bak ...
- ubuntu下出现的问题-控制台更新源失败
Ubuntu下控制台输入sudo apt-get update之后出现的问题:E: Could not get lock /var/lib/apt/lists/lock - open (11: Res ...
- 临时更换hadoop-ugi
在用spark读写hdfs数据时,有时候当前用户对要读写的hdfs路径没有权限,需要临时改变用户去读写hdfs,操作完后回到原来的用户.我们的hdfs是没有权限认证的,一开始通过下面代码的方式来实现. ...
- python之路 - 爬虫
网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁.自动索引.模拟程序或者蠕 ...
- JDBC增删改查简单测试
首先编写一个entity以便与数据库表文件相对应 lyTable.java public class LyTable implements java.io.Serializable { private ...
- C# WinForm 中英文实现, 国际化实现的简单方法
来源:http://www.jb51.net/article/45675.htm,今天看到了借鉴过了,保存一下,下次开发直接用嘻嘻 软件行业发展到今天,国际化问题一直都占据非常重要的位置,而且应该越来 ...
- 执行jar文件生成pdf报错,Unsupported URL <file:///home
java -Djava.library.path=/usr/local/lib/ruby/gems/1.8/gems/sharp_office-1.0.1/ext/sigar -jar /usr/lo ...
- .Net组件程序设计之远程调用(一)
.Net组件程序设计之远程调用(一) 1应用程序域 我们知道我们写的C#代码是在操作系统逻辑体系结构中最上层的,然而操作系统本身是不会认识C#代码的,它只认识机器代码.那我们写的程序经过编译后是编译成 ...
- 【干货】JS版汉字与拼音互转终极方案,附简单的JS拼音输入法
前言 网上关于JS实现汉字和拼音互转的文章很多,但是比较杂乱,都是互相抄来抄去,而且有的不支持多音字,有的不支持声调,有的字典文件太大,还比如有时候我仅仅是需要获取汉字拼音首字母却要引入200kb的字 ...
- 微冷的雨之Java中的多线程初理解(一)
在讲解多线程前,我们必须理解什么是多线程?而且很多人都会将进程和线程做对比. 进程和线程 进程:进程是操作系统结构的基础,是一次程序的执行,是一个程序及其数据在处理机上顺序执行时所发生的活动,是程序在 ...