[学习笔记—Objective-C]《Objective-C 程序设计 第6版》第八章 继承

时间:2022-05-07 09:56:07
  1. 在子类使用实例变量,必须先在接口部分声明,在实现部分声明的实例变量是私有的
  2. ClassB继承ClassA,ClassC继承ClassB. ClassC能继承ClassB的所有方法和实例变量,同时也一次继承A的所有方法和实例变量。

Part1. 继承 扩展

1. 矩形类

  • 声明文件
#import <Foundation/Foundation.h>

@interface Rectangle : NSObject

@property int width, height;


-(void) setWidth: (int) w andHeight: (int) h;

-(int) area;
-(int) perimeter;

@end
  • 实现文件
#import "Rectangle.h"

@implementation Rectangle

@synthesize width, height;

-(void) setWidth:(int)w andHeight:(int)h
{
    width = w;  
    height = h;
}

-(int) area
{
    return width * height;
}

-(int) perimeter
{
    return (width + height) * 2;
}

@end

2. 扩展矩形类:

Square类继承Rectangle类,用setSide:方法设置正方形的大小,并利用Rectangle类的方法计算正方形的面积。

  • 接口文件
#import "Rectangle.h"

@interface Square : Rectangle //继承

-(void) setSide : (int) s;
-(int) side;

@end
  • 声明文件
@implementation Square : Rectangle //继承

-(void) setSide:(int)s
{    
    [self setWidth: s andHeight: s]; 
}

-(int) side
{
    return self.width; //执行取值方法width而不是直接获取实例变量width
}

//side 方法不能直接获取Rectangle的实例变量width(私有的),但是取值方法是继承父类的,获取width的值。
@end

3. 给矩形添加原点

XYPoint.h接口文件

#import <Foundation/Foundation.h>

@interface XYPoint : NSObject

@property int x, y; 

-(void) setX: (int) xVal andY: (int) yVal;

@end

XYPoint.m实现文件

#import "XYPoint.h"

@implementation XYPoint

@synthesize x, y;

-(void) setX:(int)xVal andY:(int)yVal
{
    x = xVal;
    y = yVal;
}

@end

Rectangle.h接口文件

#import <Foundation/Foundation.h>

@class XYPoint; //表明 XYPoint是一个类

@interface Rectangular : NSObject

@property int width, height;

-(void) setOrigin: (XYPoint *) pt;
-(XYPoint *) origin;

-(void) setWidth: (int) w andHeight: (int) h;
-(int) area;
-(int) perimeter;

@end

Rectangle.m实现文件

#import "Rectangular.h"

@implementation Rectangular
{
    XYPoint *origin; //原点
}


@synthesize width, height;


-(void) setWidth:(int)w andHeight:(int)h
{
        width = w;
        height = h;
}

-(int) area
{
    return width * height;
}

-(int) perimeter
{
    return (width + height) * 2;
}

-(void) setOrigin:(XYPoint *)pt
{
    origin = pt; //复制指针,不是对象内容
}


-(XYPoint *) origin
{
    return origin; //存取方法origin;
}
@end

测试程序:

#import <Foundation/Foundation.h>
#import "Rectangular.h"
#import "XYPoint.h"


int main(int argc, const char * argv[]) {
    @autoreleasepool
    {
        Rectangular *myRect  = [[Rectangular alloc] init];
        XYPoint     *myPoint = [[XYPoint     alloc] init];

        [myRect setWidth:5 andHeight:8];
        [myPoint setX:100 andY:200];

        myRect.origin = myPoint; //复制指针

        NSLog(@"Rectangle w = %i, h = %i", myRect.width, myRect.height);

        NSLog(@"Area = %i, Perimeter = %i", [myRect area], [myRect perimeter]);

        NSLog(@"Origin is at (%i, %i)", myRect.origin.x, myRect.origin.y);

    }
    return 0;
  • myPoint 和 pt 同时指向同一地址,若改变myPoint指向的地址中的内容,pt指向的内容也会更改。

解决办法:

-(void) setOrigin:(XYPoint *)pt
{

    if(!origin)//origin为0时执行
    {
        origin = [[XYPoint alloc] init];      
    }
    origin.x = pt.x;
    origin.y = pt.y; //复制地址内容,而不是地址
}

Part2. 覆写方法

  • 覆写:使用和父类相同的名称的方法,相同的返回类型,相同的参数数目。目的可以更改父类方法的定义。

  • 创建子类的原因

    1. 继承一个类的函数,加入一些新的实例变量和方法。
    2. 创建一个类的特别版本(图形对象的特定类型)。
    3. 通过覆写一个或多个方法来改变类的默认行为。