- 在子类使用实例变量,必须先在接口部分声明,在实现部分声明的实例变量是私有的
- 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. 覆写方法
覆写:使用和父类相同的名称的方法,相同的返回类型,相同的参数数目。目的可以更改父类方法的定义。
-
创建子类的原因
- 继承一个类的函数,加入一些新的实例变量和方法。
- 创建一个类的特别版本(图形对象的特定类型)。
- 通过覆写一个或多个方法来改变类的默认行为。