A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© .Drenched 中级黑马   /  2014-5-2 16:34  /  2465 人查看  /  21 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

1>重写-init方法:
在@interface声明

@property NSString *name;

在@implementation实现如下:
  1. - (id)init
  2. {
  3.     if ( self = [super init] )
  4.     {
  5.         _name = @"Jack";
  6.     }
  7.     return self;
  8. }
复制代码
2>自定义构造方法

在@interface声明

- (id)initWithName:(NSString *)name;

在@implementation实现如下:


  1. - (id)initWithName:(NSString *)name
  2. {

  3.     if ( self = [super init] )
  4.     {
  5.         _name = name;
  6.     }
  7.    
  8.     return self;
  9. }
复制代码

我的问题是:自定义构造方法有什么用?

评分

参与人数 1技术分 +1 收起 理由
脸皮猴 + 1

查看全部评分

21 个回复

倒序浏览
本帖最后由 执着的土豆 于 2014-5-2 17:25 编辑

默认的构造方法,也就是init方法,它是不接收任何参数的。因此,在实际开发中,为了方便,会经常自定义构造方法。用来在给对象初始化的时候实现设置默认参数。
举个简单的例子,来说明他的好处吧。
如果要定义10个学生,他们的姓名都是10岁。那么如果不用构造方法,那么你创建出来的对象需要一个个赋值。简易代码如下:
1、student 的年龄构造方法采取默认的情况
[student *s1]=[[student alloc] init];
  s1.age=10;
[student *s2]=[[student alloc] init];
    s2.age=10;
。。。。。。。。省略8个初始化。
2、采取自定义构造方法

@implementation student

-  (id)initWithAge:(int)age
{
    if(self=[super init])
  {
       _age=age;
  }
   return self;
}

调用的时候直接写
student *s1=[[student alloc] initWithAge:10]; //这样初始化的学生对象默认的年龄就是10.  如果参数越多,越能体现出调用时的简便。

评分

参与人数 1技术分 +1 收起 理由
脸皮猴 + 1

查看全部评分

回复 使用道具 举报
执着的土豆 发表于 2014-5-2 17:13
默认的构造方法,也就是init方法,它是不接收任何参数的。因此,在实际开发中,为了方便,会经常自定义构造 ...

默认的构造方法不是new?new分为分配存储空间和初始化init,只要修改默认初始化值就可以了。
比方说如下定义,将age的初始值修改成了10。
  1. - (id)init
  2. {
  3.     if ( self = [super init] )
  4.     {
  5.         _age = 10;
  6.     }

  7.     return self;
  8. }
复制代码

照这样,那我自定义构造方法的用途是什么?

回复 使用道具 举报
如果“用来在给对象初始化的时候实现设置默认参数。”我重构init就行了,何必要自定义构造方法呢?
回复 使用道具 举报
本帖最后由 yaozeyang_2014 于 2014-5-2 17:27 编辑

其实构造方法的目的就是为了给成员函数初始化的。假如你在@interface里面声明了一些成员变量,因为在@interface里面是不能直接初始化的,你在创建对象的时候,直接调用你自定义的构造函数给成员变量赋初始值,这样做的目的可以在快速创建对象的时候也顺带让属性带有初始值。楼主可以输出试验结果看一下,最好是重写一下description,这样就可以看到对象的属性值。
回复 使用道具 举报
.Drenched 发表于 2014-5-2 17:24
默认的构造方法不是new?new分为分配存储空间和初始化init,只要修改默认初始化值就可以了。
比方说如下 ...

你这样自定义初始化的用途就是让创建出来的student对象的年龄默认等于10 啊。    如果需要他等于10,那么在 初始化后,就不需要再次对他进行赋值了。   
回复 使用道具 举报
yaozeyang_2014 发表于 2014-5-2 17:26
其实构造方法的目的就是为了给成员函数初始化的。假如你在@interface里面声明了一些成员变量,因为在@inter ...

我问的是自定义构造方法与重写-init方法的区别。自定义构造方法与重写-init方法都可以给成员变量定义初始值。
回复 使用道具 举报
.Drenched 发表于 2014-5-2 17:26
如果“用来在给对象初始化的时候实现设置默认参数。”我重构init就行了,何必要自定义构造方法呢? ...

我的理解是,自定义构造方法其实就是重构init方法。  
回复 使用道具 举报
执着的土豆 发表于 2014-5-2 17:28
你这样自定义初始化的用途就是让创建出来的student对象的年龄默认等于10 啊。    如果需要他等于10,那么 ...

额,我知道这样就给成员变量age初始化值为10,因为我重写了init方法,我的意思,我现在也可以自定义构造方法来实现给成员变量age初始值为10.这两者的区别在哪里,既然我重写init就行了,那我何必要自定义构造方法呢?
回复 使用道具 举报
.Drenched 发表于 2014-5-2 17:29
我问的是自定义构造方法与重写-init方法的区别。自定义构造方法与重写-init方法都可以给成员变量定义初始 ...

自定义构造方法,直接让对象调用你自定义的方法就好,是可以初始化的啊,如果你重写方法的话,也是可以的,因为调用顺序是子类比父类优先,所以一样可以初始化成员变量。
回复 使用道具 举报
执着的土豆 发表于 2014-5-2 17:31
我的理解是,自定义构造方法其实就是重构init方法。

不是的,这两者肯定有区别,区别在于一个是写死的,一个是可以接收参数的,因为init重构也是写死的,但是怎么接收,我不知道,问题在这里。
回复 使用道具 举报
.Drenched 发表于 2014-5-2 17:31
额,我知道这样就给成员变量age初始化值为10,因为我重写了init方法,我的意思,我现在也可以自定义构造 ...

首先你重写init方法,是不是只能写
- (id)init  
只能跟NSObject中的init方法名一样,这样的我理解我重写

如果你需要给他传递一个参数,并且将这个参数做一些操作,那么你重写init方法是做不到的。因为你没法来接受那个参数。 这个时候就需要用到自定义构造方法了。
如下面的例子,你初始化给的是多少,那么创建出来的对象他的age值就是多少。
-  (id)initWithAge(int)age
{
    if(self=[super init])
  {
       _age=age;
  }
   return self;
}
回复 使用道具 举报
yaozeyang_2014 发表于 2014-5-2 17:34
自定义构造方法,直接让对象调用你自定义的方法就好,是可以初始化的啊,如果你重写方法的话,也是可以的 ...

怎么“直接让对象调用你自定义的方法”?比如?
回复 使用道具 举报
我在1楼给你回复的时候,想着要不要直接写死 _age=10;   那样写虽然也可以实现,并且在主函数调用的时候不需要再给他赋值,但是万一后期需要初始化一个年龄20岁的student对象时,那么这个方法就显的很鸡肋。  
回复 使用道具 举报
.Drenched 发表于 2014-5-2 17:40
怎么“直接让对象调用你自定义的方法”?比如?

-  (id)initWithAge: (int)age
{
    if(self=[super init])
  {
       _age=age;
  }
   return self;
}

以这个为例子,在主函数调用的时候如下:
student *s=[[student alloc] initWithAge:20];  这样直接就给他分配了存储空间,并且设置内部成员变量_age的值为20,交给指针s来操作。
回复 使用道具 举报
.Drenched 发表于 2014-5-2 17:40
怎么“直接让对象调用你自定义的方法”?比如?

如果你是视频没看完的话,我觉得你看完后面的视频,你就明白这个问题了。   多练习一下就掌握了。  
回复 使用道具 举报
执着的土豆 发表于 2014-5-2 17:42
我在1楼给你回复的时候,想着要不要直接写死 _age=10;   那样写虽然也可以实现,并且在主函数调用的时候不 ...

就算你自定义重构方法,也要一个一个的写阿,你的成员变量有几个就要写几个重构方法,先声明后实现。而不是你说的几个参数可以写在一个重构方法里面。
回复 使用道具 举报
执着的土豆 发表于 2014-5-2 17:46
-  (id)initWithAge: (int)age
{
    if(self=[super init])

重写init不一样么?好像也是一样的。
回复 使用道具 举报
.Drenched 发表于 2014-5-2 17:48
就算你自定义重构方法,也要一个一个的写阿,你的成员变量有几个就要写几个重构方法,先声明后实现。而不 ...

其实在我的理解来看,重写就是最简单的自定义构造方法。     几个参数当然可以写在一个重构方法里啊。 只不过方法名字会长一点,需要几个参数,就要写几个变量类型和变量名,然后在调用的时候也一样,需要根据方法有几个行参,就传递几个实参过去。

并且我理解的自定义构造方法的好处。
默认的new的不好的一点: 在给对象分配了内存地址后,就是初始化了,在这里会先给对象的一些成员变量赋值为0,然后你在调用的时候,再给他赋值,相当于赋了两次值。
而你写了自定义构造方法后,调用的时候,直接初始化,就会时你要的值,不需要再次赋值,总共赋值1次。
回复 使用道具 举报
.Drenched 发表于 2014-5-2 17:49
重写init不一样么?好像也是一样的。

我觉得我无法再解释的更清楚了,如果你还是无法理解,建议再好好看下视频,然后练习一下,再回头看的时候,可能就会觉得像这么回事。  
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马