Fork me on GitHub

继承(子类) 初始化 深层复制

小常识:可以在使用的数据类型中为实例变量和方法指定协议名称。这样,可以给Objective-C的编译器提供更多的信息,从而有助于检查代码中的错误。

-(void)setObjectValue:(id<NSCopying>)obj ;  

编译器知道,你期望任意类型的对象,只要其遵守该协议。

@protocol NSCopying

-(void)copyWithZone:(NSZone*)zone;

@end

@protocol NSCoding

-(void)encodeWithCoder:(NSCoder*)acoder;

-(id)initWithCoder:(NSCoder*)aDecoder;

@end

 

@Class Tire;

@Class Engine;

@interface Car:NSObject<NSCopying,NSCoder>

{

  NSString *name;

  NSMutableArray *tires;

  Engine *engine;

}

-(void)setTire:(Tire*)tire atIndex:(int)index;

-(Tire*)tireAtIndex:(int)index;

-(void)print;

@property(copy)NSString *name;

@property(retain)Engine *engine;

@end

 

@implementation Car

-(id)copyWithZone:(NSZone*)zone

{

  Car *carCopy;

  carCopy=[[[self class] allocWithZone:zone]

              init];

  carCopy.name=self.name;    

          //name属性复制其字符串对象

  Engine *engineCopy;

  engineCopy=[[engine copy]autorelease];

  carCopy.engine=engineCopy;

/*或者

  engineCopy=[engine copy];       retainCount +1

  carCopy.engine=engineCopy;    retainCount +1

  [engineCopy release];    */    retainCount -1

 

  int i;

  for(i=0;i<4;i++)

  {

    Tire *tireCopy;

    tireCopy=[[self tireAtIndex:i]copy];

    [tireCopy autorease];

    [carCopy setTire:tireCopy 

         atIndex:i];

  }

   return carCopy;

}

-(id)init

{

  if(self=[super init])

  {

    tires=[[NSMutableArray alloc]init];

    int i;

    for(i=0;i<4;i++)

    {

      [tires addObject:[NSNull null]];

    }  

     }  

     return self;

}

-(void)setTire:(Tire*)tire atIndex:(int)index

{

  [tires replaeObjectAtIndex:index withObject:tire];

}

-(tire*)tireAtIndex:(int)index

{

  Tire *tire;

  tire=[tires objectAtindex:index];

  return tire;

}

-(void)dealloc

{

  [tires release];

  [engine release];

  [super dealloc];

}

-(void)print

{

  int i;

  for(i=0;i<4;i++)

  {

    NSLog(@"%@",[self tireAtIndex i]);

  }

  NSLog(@"%@",engine);

}
 

 

 

 

@interface:Tire:NSObject<NSCopying>

{

  float pressure;

  float treadDepth;

}

-(id)initWithPressure:(float)pressure;

-(id)initWithTreadDepth:(float)treadDepth;

-(id)initWithPressure:(float)pressure TreadDepth:(float)treadDepth;  

                  //指定初始化函数(designating initializer)

@property float pressure;

@property float treadDepth;

@end

 

@implementation:Tire

@synthesize pressure;

@synthesize treadDepth;

-(id)copyWithZone:(NSZone*)zone

{

  id tireCopy;

  /*   虽然这样写没错,但是破坏了封装原则,父类改变了子类的选择

  if([[self class]  is memberOfClass [Tire class]])

  {

    tireCopy=[[Tire  allocWithZone:zone]

          initWithPressure:pressure

          treadDepth:treadDepth];

  }

  else

  {

      tireCopy=[[[self class]allocWithZone:zone]    

         initWithPressure:pressure TreadDepth:treadDepth 

               rainHanding:rainHanding  

               snowHanding:snowHanding];

    [self class ]这里代表Tire的子类,调用子类初始化方法

  }

  */

  tireCopy=[[[self class]  allocWithZone:zone]

          initWithPressure:pressure

          treadDepth:treadDepth];

  return tireCopy;

}

-(id)initWithPressure:(float)p TreadDepth:(float)td

{

  //此方法为  指定初始化函数(designated initializer)  Tire类的所有

初始化方法使用此函数执行初始化操作。子类使用其超类的  指定初始化函数

实现超类初始化(通常接受参数最多的初始化方法最终成为  指定初始化函数)

  if(self=[super init])   //调用父类init方法,很重要,确保超类获得对象并使其运行;

  {

    pressure=p;

    treadDepth=td;

    }

}

-(id)init

{

  if(self=[self initWithPressure:(float)34

          TreadDepth:(float)20]){

  }

  return self;

}

-(id)initWithPressure:(float)pressure

{

  if(self=[self initWithPressure:(float)pressure

          TreadDepth:(float)20]){

  }

  return self;

}

-(id)initWithTreadDepth:(float)treadDepth

{

  if(self=[self initWithPressure:(float)34

          TreadDepth:(float)treadDepth]){

  }

  return self;

}

...  ...

 

 

@interface AllWeatherRadia:Tire   因AllWeatherRadia是Tire子类

            已经获得了Tire的所有属性,包括对协议的遵守

            所以不需要<NSCopying>

{

  float rainHanding;

  float snowHanding;

}

-(id)initWithPressure:(float)p TreadDepth:(float)td

 

@property float rainHanding;

@property float snowHanding;

@end

 

@implementation AllWeatherRadia

@synthesize rainHanding;

@synthesize snowHanding;

-(id)copyWithZone:(NSZone*)zone

{

  AllWeatherRadia *awr;

  awr=[super copyWithZone:zone];

  awr.rainHanding=self.rainHanding;

  awr.snowHanding=self.snowHanding;

  return awr;

-(id)initWithPressure:(float)p TreadDepth:(float)td 

{

  if(self=[self  initWithPressure:(float)p TreadDepth:(float)td  

                               rainHanding:(float)23.7f  

                    snowHanding:(float)42.5f])

  {

  }

    return self;

}

-(id)initWithPressure:(float)p TreadDepth:(float)td  

               rainHanding:(float)rh  

               snowHanding:(float)sh

{

  if(self=[super initWithPressure:(float)p TreadDepth:(float)td])

  {

    rainHanding=rh;

    snowHanding=sh;

  }

    return self;

}

posted on 2012-02-23 11:57  pengyingh  阅读(482)  评论(0编辑  收藏  举报

导航