在objective-c中浅谈面向对象

余磊 余磊     2022-08-29     485

关键词:

 接触面向对象也有一段时间了,当时是通过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.在接口中方法只有声明,没有实现,方法前面的减号代表此方法是对象方法,如果是+号的话,说明是类方法,就是说类可以直接访问此方法。

            [email protected] 和 @end是成对出现的,@end代表接口定义的结束

            6.上面得成员变量定义成了公有的,这在开发中是极少见的,这里为了方便练习才这么写的,一般把成员变量定义为私有的然后在定义get,set方法去操作成员变量

      这样才起到了封装,不要把自己的手直接伸入到类中,要通过类提供的方法来操作类的成员变量。

 

 

        [email protected] 实现部分

            实现部分文件的扩展名为.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来声明类方法的实现

                  [email protected]和@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->[email protected]"爱咋咋地";
         
        //调用成员方法
        [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];

浅谈面向对象

其实面向对象,原型在JavaScript中是属于底层的知识点,但是在没有基础的情况下,甚至在学习的过程中,对于面向对象都是稀里糊涂的感觉,但是如果你学通了,你就发现它也不过如此,我学习面向对象这一章已经有一段时间... 查看详情

浅谈面向对象

面向对象:顾名思义就是站在对象的角度思考问题,我们把多个功能合理的放到不同对象里,强调的是具备某些功能的对象。具备某种功能的实体,称为对象,面向对象很符合我们常规的思维方式,稳定性好,可重用性强,易于... 查看详情

浅谈javascript的面向对象思想

面向对象的三大基本特性封装(把相关的信息(无论数据或方法)存储在对象中的能力)继承(由另一个类(或多个类)得来类的属性和方法的能力)多态(一个对象在不同情况下的多种形态)定义类或对象第一种:基于Object对象varperson... 查看详情

浅谈结构化方法与面向对象方法

浅谈结构化方法与面向对象方法一.引言   在软件开发过程中,有很多不同的软件开发方法。选取合适的软件开发方法,对于软件开发的过程和结果有着非常重要的影响。我们知道自软件工程发展以来诞生了很多不同... 查看详情

浅谈js面向对象与深入php面向对象

js面向对象:  类?什么是类?类是一些具有相同特征的对象的集合  什么是对象?就是具体到某一个事物了,都可以叫做对象类,通过function定义类,在js里类的本质是函数类和函数天生有两个属性,一个是prototype,一个是__... 查看详情

浅谈javascript面向对象

我们常用的两种编程模式POP--面向过程编程(Process-orientedprogramming)       面向过程编程是以功能为中心来进行思考和组织的一种编程方法,它强调的是系统的数据被加工和处理的过程,在程序设计中主要... 查看详情

浅谈javascript面向对象

我们常用的两种编程模式POP--面向过程编程(Process-orientedprogramming)       面向过程编程是以功能为中心来进行思考和组织的一种编程方法,它强调的是系统的数据被加工和处理的过程,在程序设计中主要... 查看详情

浅谈objective-c对象初始化的三类程序猿

...让人眼前一亮的初始化方式》的文章。什么?!初始化?Objective-C!好吧,吓哔哔~~~ 一、普通程序猿普通程序员使用最常见路人姿势等场。普普通通,纯属陆仁贾。1UIView*v=[UIViewalloc]initWithFrame:CGRectMake(0,0,200,100)];2v.backgroundColo... 查看详情

从数组循环左移问题中浅谈考研算法设计的规范代码

     问题:设将n(n>1)个整数存放到一维数组R中。设计一个算法,将R中的序列循环左移p(0<p<n)个位置,即将R中的数据由{X0,X1,...,Xn-1}变换为{Xp,Xp+1,...,Xn-1,X0,X1,...,Xp-1}。要求:写出本题的算法描述。&n... 查看详情

浅谈——面向对象(代码片段)

面向对象编程——ObjectOrientedProgramming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行... 查看详情

浅谈面向对象和继承(代码片段)

1.面向对象和面向过程的区别  面向过程:注重代码的过程  面向对象:注重代码的结果2.面向对象三大特性  抽象  封装 继承 多态(JS不存在多态)3.什么是一个构造函数  new一个关键字函数 创建一... 查看详情

浅谈对面向对象的理解

面向过程与面向对象的区别:面向过程是一种直接的编程方法,它是按照编程语言的思路考虑问题。通过顺序执行一组语句来实现一个功能,这些语句的执行过程就是整个程序。面向对象是一种抽象度更高的编程方法。它的目标... 查看详情

浅谈结构化方法和面向对象方法的理解

  人对于世界的认识是不断的在深化的,人对于世界的改造方式也是在不断的改变的,在程序的世界里,并没有一种绝对的对,或者错,也没有绝对的好或者是坏,只要能解决一个问题,那这个方法就是可行的,就是好的,所... 查看详情

浅谈javascript的面向对象程序设计

  本文继续讲解JavaScript的面向对象程序设计。继承是面向对象语言中的一个基本概念,面向对象语言支持两种继承实现方式:接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际的方法。但是在JavaScript中... 查看详情

面向对象——浅谈弊端

转自知乎我个人觉得很有用我就将其转载过来,大家有兴趣可以看下。没有人还记得面向对象原本要解决的问题是什么,这就是我们现在所面临的困境。面向对象原本要解决什么(或者说有什么优良特性)似乎很简单,但实际又... 查看详情

浅谈javascript中面向对象之对象

一、对象1.1创建对象Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象。一个简单的对象创建:varPeople={name:"eavan",age:24,getName:function(){alert(this.name);//eavan}}使用的时候就可以用People.name,获取People这个... 查看详情

objective-c面向对象

(一)对象(1)l类和接口的名称与其他语言的区别//              类        接口//objective-c   @interfa 查看详情

day10浅谈面向对象编程

面向对象编程:第一步找名词,名词是问题域中的。       第二步概括名词设计成类。某些名词可以浓缩包含到其它名词中,成为其属性。                 &nb... 查看详情