类与继承

编写一个形状的类(Shape),编写一个他的继承类 长方形(Rectangle)                                        类方法中可以访问类方法,但不能访问对象方法【因为类方法中没有实例变量】

1、类(Shape)                                                                                                               对象方法中可以访问对象方法和类方法
首先右键工程 [New File],新建一个[Objective-C Class]点击[next]填写类名 
Shape
头文件源码如下:
 
////  Shape.h
//  sample002
////  Created by on 13-1-13.
//  Copyright (c) 2013年 echoliu. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Shape : NSObject{
    int length;
    int width;
    int height;
}
//setter 相当于c# java中的set
-(void) setLength:(int) l;
-(void) setWidth:(int) w;
-(void) setHeight:(int) h;
//get 相当于c# java中的get
-(int) length;
-(int) width;
-(int) height;
//print 一个方法 打印
-(void) print;
@end
 
m文件源码如下:
 
////  Shape.m
//  sample002
////  Created by echoliu on 13-1-13.
//  Copyright (c) 2013年 echoliu. All rights reserved.
//

#import "Shape.h"

@implementation Shape

//setter 对头文件的实现
-(void) setLength:(int) l{
    length=l;
}

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

-(void) setHeight:(int) h{
    height=h;
}

//getter
-(int) length{
    return  length;
}

-(int) width{
    return width;
}

-(int) height{
    return height;
}
//print 对头文件的实现
-(void) print{
    NSLog(@"this shape length: %i %i height: %i",length,width,height);
}
@end
 
在main中的测试代码
Shape *shape=[[Shape alloc] init];
        [shape setHeight:100];
        [shape setWidth:200];
        [shape setLength:300];
        [shape print];
代码说明
Shape *shape=[[Shape alloc] init]; 初始化一个Shape类,在java c#中,我们一般是Shape shape=new Shape();的方式,而objectc中,一般采用中括号来执行方法,alloc 表示分配内存,init 表示初始化内存。

[shape setHeight:100]; 调用方法 setHeight
 
 最后[run]按钮实现输出
2013-01-1400:03:00.920 sample002[742:303] this shape length: 300 200 height: 100
 2. 类长方形 Rectangle 
他继承与Shape类
方法同上新建一个Rectange的object-c class 
头文件
 
////  Rectangle.h
//  sample002
////  Created by on 13-1-13.
//  Copyright (c) 2013年 echoliu. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Shape.h"
@interface Rectangle : Shape{
    int size;
}

//setter
-(void) setSizeWidth:(int) w withHeight :(int) h;

-(void) printSize;

@end
 
实现文件 继承了Shape类,例如里面的print方法,在h文件中并没有定义,当在m文件中确实现了该方法,这个跟其他语言的接口是类似的功能。
 
////  Rectangle.m
//  sample002
////  Created by echoliu on 13-1-13.
//  Copyright (c) 2013年 echoliu. All rights reserved.
//

#import "Rectangle.h"
@implementation Rectangle
-(void) setSizeWidth:(int)w withHeight:(int)h{
    size=w*h;
}

-(void) printSize{
    NSLog(@"The Size is %d",size);
}

-(void) print{
    NSLog(@"The Child Function Size is %d",size);}
@end
 
main中的调用
 
#import <Foundation/Foundation.h>
#import "Shape.h"
#import "Rectangle.h"int main(int argc, constchar * argv[])
{

    @autoreleasepool {
       
        Shape *shape=[[Shape alloc] init];//初始化一个shape类
        [shape setHeight:100];
        [shape setWidth:200];
        [shape setLength:300];
        [shape print];
        // insert code here...
        NSLog(@"Hello, World!");
        //shape for rectangle
        Rectangle *rect=[[Rectangle alloc] init];

//使用父类方法
        [rect setWidth:88];
        [rect setHeight:88];
        //打印结果 
        [rect printSize];
        [rect print];
        //使用类方法
        [rect setSizeWidth:200withHeight:300 ];
        [rect printSize];
        [rect print];

    }
    return0;
}
 
输出
2013-01-15 20:51:50.178 sample002[1991:303] this shape length: 300 200 height: 100
2013-01-15 20:51:50.181 sample002[1991:303] Hello, World!
2013-01-15 20:51:50.181 sample002[1991:303] The Size is 0 
2013-01-15 20:51:50.182 sample002[1991:303] The height widht   is 88 88
2013-01-15 20:51:50.182 sample002[1991:303] The Size is 60000 
2013-01-15 20:51:50.182 sample002[1991:303] The height widht   is 300 200
2013-01-15 20:51:50.183 sample002[1991:303] the zheng fangxing
 

继承.note
 
 
1.俩个类里面的东西相同,用继承  。
    但是不要乱用,虽然语法上通过,但是设计上也要合理【如:Person类和Car类】       类方法不能访问成员变量,因为类方法
2.好处:建立类之间的关系;避免代码重复;分工明确,更加清晰

3.继承时子类和父类,谁先建立都是一样的 ,与顺序无关

4. 子类中不能有父类的成员变量
    子类可以有父类的方法(重写)),优先在自己的类里面找方法
5. NSObject是所有类的根类(基类,超类),用到父类是要记得导入
继承是类中的一个重要的特性,他的出现使得我们没必要别写重复的代码,可重用性很高。当然OC中的继承和Java中是一样的,没多大区别,这里在看一个例子吧:
首先来看一下父类:Car
Car.h
[objc]  view plaincopy
1. //  
2. //  Car.h  
3. //  06_ExtendDemo  
4. //  
5. //  Created by jiangwei on 14-10-11.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import <Foundation/Foundation.h>  
10.   
11. @interface Car : NSObject{  
12.     NSString *_brand;  
13.     NSString *_color;  
14. }  
15.   
16. - (void)setBrand:(NSString *)brand;  
17. - (void)setColor:(NSString *)color;  
18. - (void)brake;  
19. - (void)quicken;  
20.   
21. @end  
在Car类中定义了两个属性,以及一些方法
Car.m
[objc]  view plaincopy
1. //  
2. //  Car.m  
3. //  06_ExtendDemo  
4. //  
5. //  Created by jiangwei on 14-10-11.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import "Car.h"  
10.   
11. @implementation Car  
12. - (void)setBrand:(NSString *)brand{  
13.     _brand = brand;  
14. }  
15. - (void)setColor:(NSString *)color{  
16.     _color = color;  
17. }  
18. - (void)brake{  
19.     NSLog(@"刹车");  
20. }  
21. - (void)quicken{  
22.     NSLog(@"加速");  
23. }  
24. @end  
方法的实现


在来看一下子类:
Taxi.h
[objc]  view plaincopy
1. //  
2. //  Taxi.h  
3. //  06_ExtendDemo  
4. //  
5. //  Created by jiangwei on 14-10-11.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import "Car.h"  
10.   
11. @interface Taxi : Car{  
12.     NSString *_company;//所属公司  
13. }  
14.   
15. //打印发票  
16. - (void)printTick;  
17.   
18. @end  
看到Taxi类继承了父类Car,这里需要导入父类的头文件,然后在Taxi类中多了一个属性和方法
Taxi.m
[objc]  view plaincopy
1. //  
2. //  Taxi.m  
3. //  06_ExtendDemo  
4. //  
5. //  Created by jiangwei on 14-10-11.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import "Taxi.h"  
10.   
11. @implementation Taxi  
12.   
13. - (void)printTick{  
14.     [super brake];  
15.     [self brake];  
16.     NSLog(@"%@出租车打印了发票,公司为:%@,颜色为:%@",_brand,_company,_color);  
17. }  
18.   
19. @end  
对方法的实现,这里我们看到实现文件中是不需要导入父类Car的头文件的,因为可以认为,Taxi.h头文件中已经包含了Car的头文件了。而且,这里可以使用super关键字来调用父类的方法,同时这里我们也是可以用self关键字来调用,这里看到其实这两种方式调用的效果是一样的,当我们在子类重新实现brake方法的时候(Java中的重写概念),那么这时候super关键字调用的还是父类的方法,而self调用的就是重写之后的brake方法了。同样,我们也是可以使用父类中的属性。


再看一下另外一个子类:
Truck.h
[objc]  view plaincopy
1. //  
2. //  Truck.h  
3. //  06_ExtendDemo  
4. //  
5. //  Created by jiangwei on 14-10-11.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import "Car.h"  
10. //卡车类继承Car  
11. @interface Truck : Car{  
12.     float _maxWeight;//最大载货量  
13. }  
14.   
15. //覆盖父类的方法brake  
16. //优先调用子类的方法  
17. - (void)brake;  
18.   
19. - (void)unload;  
20.   
21. @end  
这里就自己定义了一个brake方法,这时候就会覆盖父类中的brake方法了。
Truck.m
[objc]  view plaincopy
1. //  
2. //  Truck.m  
3. //  06_ExtendDemo  
4. //  
5. //  Created by jiangwei on 14-10-11.  
6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
7. //  
8.   
9. #import "Truck.h"  
10.   
11. @implementation Truck  
12.   
13. - (void)brake{  
14.     [super brake];  
15.     NSLog(@"Truck类中的brake方法");  
16. }  
17.   
18. - (void)unload{  
19.     [super brake];//调用父类的方法  
20.     [self brake];//也是可以的  
21.     NSLog(@"%@的卡车卸货了,载货量:%.2f,汽车的颜色:%@",_brand,_maxWeight,_color);  
22. }  
23.   
24. @end  
这里就可以看到,我们会在brake方法中调用一下父类的brake方法,然后在实现我们自己的逻辑代码。
原文地址:https://www.cnblogs.com/GhostKZShadow/p/5105416.html