OC面向对象的三大特性
@public的成员可以被随意赋值,应该使用set方法和get方法来管理成员的访问(类似机场的安检、水龙头过滤,过滤掉不合理的东西),比如僵尸的生命值不能为负数
#import <Foundation/Foundation.h>
// 声明
@interface Car : NSObject
{
int _wheels; // 轮子个数
}
/*set方法*/
- (void) setWheels:(int)wheels;
/*get方法*/
- (int) wheels;
@end
@implementation Car
// set方法的实现
- (void) setWheels:(int)wheels
{
// 对外面传进来的轮子数进行过滤
if (wheels<=0)
{
wheels = 1;
}
_wheels = wheels;
}
// get方法的实现
- (int) wheels
{
return _wheels;
}
@end
1 /** 2 4.设计Car类 3 1> 属性 4 * 速度 5 6 2> 方法 7 * 属性相应的set和get方法 8 * 一个对象方法跟其他车子比较车速,返回速度差 9 * 一个类方法比较两辆车的车速,返回速度差 10 */ 11 12 #import <Foundation/Foundation.h> 13 14 // 车 15 @interface Car : NSObject 16 { 17 int _speed; // 速度 18 } 19 20 // 速度的getter和setter 21 - (void)setSpeed:(int)speed; 22 - (int)speed; 23 24 // 跟其他车子比较车速,返回速度差 25 - (int)compareSpeedWithOther:(Car *)car; 26 // 比较两辆车的车速,返回速度差 27 + (int)compareSpeedBetweenCar1:(Car *)car1 andCar2:(Car *)car2; 28 @end 29 30 @implementation Car 31 // 速度的getter和setter 32 - (void)setSpeed:(int)speed 33 { 34 _speed = speed; 35 } 36 - (int)speed 37 { 38 return _speed; 39 } 40 41 // 跟其他车子比较车速,返回速度差 42 - (int)compareSpeedWithOther:(Car *)car 43 { 44 // 第1种思路 45 // return _speed - [car speed]; 46 47 // 第2种思路 48 return [Car compareSpeedBetweenCar1:self andCar2:car]; 49 } 50 51 // 比较两辆车的车速,返回速度差 52 + (int)compareSpeedBetweenCar1:(Car *)car1 andCar2:(Car *)car2 53 { 54 return [car1 speed] - [car2 speed]; 55 } 56 @end
直接可以用类名来执行的方法(类本身会在内存中占据存储空间,里面有类\对象方法列表)
练习:设计一个成绩类
* C语言成绩(可读可写)
* OC成绩(可读可写)
* 总分(只读)
* 平均分(只读)
1 #import <Foundation/Foundation.h> 2 3 @interface Score : NSObject 4 { 5 int _cScore; // C语言成绩 6 int _ocScore; // OC成绩 7 8 int _totalScore;// 总分 9 int _averageScoe; // 平均分 10 } 11 12 - (void)setCScore:(int)cScore; 13 - (int)cScore; 14 15 - (void)setOcScore:(int)ocScore; 16 - (int)ocScore; 17 18 - (int)totalScore; 19 - (int)averageScore; 20 21 @end 22 23 @implementation Score 24 - (void)setCScore:(int)cScore 25 { 26 _cScore = cScore; 27 28 // 计算总分 29 _totalScore = _cScore + _ocScore; 30 _averageScoe = _totalScore/2; 31 } 32 - (int)cScore 33 { 34 return _cScore; 35 } 36 37 - (void)setOcScore:(int)ocScore 38 { 39 _ocScore = ocScore; 40 41 // 计算总分 42 _totalScore = _cScore + _ocScore; 43 _averageScoe = _totalScore/2; 44 } 45 // 监听成员变量的改变 46 47 - (int)ocScore 48 { 49 return _ocScore; 50 } 51 52 - (int)totalScore 53 { 54 return _totalScore; 55 } 56 - (int)averageScore 57 { 58 return _averageScoe; 59 } 60 @end 61 62 63 int main() 64 { 65 Score *s = [Score new]; 66 67 [s setCScore:90]; 68 [s setOcScore:100]; 69 70 [s setCScore:80]; 71 72 73 int a = [s totalScore]; 74 75 NSLog(@"总分:%d", a); 76
// Bird的声明
@interface Bird : NSObject
{
@public
int weight;
}
- (void)eat;
@end
// Bird的定义
@implementation Bird
- (void)eat {
NSLog(@"吃吃吃-体重:%d", weight);
}
@end
// Dog的声明
@interface Dog : NSObject
{
@public
int weight;
}
- (void)eat;
@end
// Dog的定义
@implementation Dog
- (void)eat {
NSLog(@"吃吃吃-体重:%d", weight);
}
@end
// Animal的声明
@interface Animal : NSObject
{
@public
int weight;
}
- (void)eat;
@end
// Animal的定义
@implementation Animal
- (void)eat {
NSLog(@"吃吃吃-体重:%d", weight);
}
@end
// Bird的声明
@interface Bird : Animal
{
@public
int height;
}
- (void)fly;
@end
// Bird的定义
@implementation Bird
- (void)fly {
NSLog(@"飞飞飞-高度:%d", height);
}
@end
// Dog的声明
@interface Dog : Animal
{
@public
int speed;
}
- (void)run;
@end
// Dog的定义
@implementation Dog
- (void)run {
NSLog(@"跑跑跑-高度:%d", speed);
}
@end
在子类中重写方法时,可以让调用者跳过这一层而调用父类中的方法。
1 /* 2 僵尸 3 4 跳跃僵尸、舞王僵尸、铁桶僵尸 5 */ 6 #import <Foundation/Foundation.h> 7 8 /* 9 super的作用 10 1.直接调用父类中的某个方法 11 2.super处在对象方法中,那么就会调用父类的对象方法 12 super处在类方法中,那么就会调用父类的类方法 13 14 3.使用场合:子类重写父类的方法时想保留父类的一些行为 15 */ 16 17 // 僵尸 18 @interface Zoombie : NSObject 19 - (void)walk; 20 21 + (void)test; 22 - (void)test; 23 24 @end 25 26 @implementation Zoombie 27 - (void)walk 28 { 29 NSLog(@"往前挪两步******"); 30 } 31 32 + (void)test 33 { 34 NSLog(@"Zoombie+test"); 35 } 36 37 - (void)test 38 { 39 NSLog(@"Zoombie-test"); 40 } 41 @end 42 43 // 跳跃僵尸 44 @interface JumpZoombie : Zoombie 45 + (void)haha; 46 - (void)haha2; 47 @end 48 49 50 @implementation JumpZoombie 51 52 + (void)haha 53 { 54 [super test]; 55 } 56 57 - (void)haha2 58 { 59 [super test]; 60 } 61 62 - (void)walk 63 { 64 // 跳两下 65 NSLog(@"跳两下"); 66 67 // 走两下(直接调用父类的walk方法) 68 [super walk]; 69 //NSLog(@"往前挪两步----"); 70 71 } 72 @end 73 74 int main() 75 { 76 //[JumpZoombie haha]; 77 JumpZoombie *jz = [JumpZoombie new]; 78 79 [jz walk]; 80 81 return 0; 82 }
5. 继承的好处
1> 当两个类拥有相同属性和方法的时候,就可以将相同的东西抽取到一个父类中
2> 当A类完全拥有B类中的部分属性和方法时,可以考虑让B类继承A类
A
{
int _age;
int _no;
}
B : A
{
int _weight;
}
// 继承:xx 是 xxx
// 组合:xxx 拥有 xxx
2.组合
A
{
int _age;
int _no;
}
B
{
A *_a;
int _weight;
}
1 #import <Foundation/Foundation.h> 2 /* 3 1.继承的好处: 4 1> 抽取重复代码 5 2> 建立了类之间的关系 6 3> 子类可以拥有父类中的所有成员变量和方法 7 8 2.注意点 9 1> 基本上所有类的根类是NSObject 10 */ 11 12 13 /********Animal的声明*******/ 14 @interface Animal : NSObject 15 { 16 int _age; 17 double _weight; 18 } 19 20 - (void)setAge:(int)age; 21 - (int)age; 22 23 - (void)setWeight:(double)weight; 24 - (double)weight; 25 @end 26 27 /********Animal的实现*******/ 28 @implementation Animal 29 - (void)setAge:(int)age 30 { 31 _age = age; 32 } 33 - (int)age 34 { 35 return _age; 36 } 37 38 - (void)setWeight:(double)weight 39 { 40 _weight = weight; 41 } 42 - (double)weight 43 { 44 return _weight; 45 } 46 @end 47 48 /********Dog*******/ 49 // : Animal 继承了Animal,相当于拥有了Animal里面的所有成员变量和方法 50 // Animal称为Dog的父类 51 // Dog称为Animal的子类 52 @interface Dog : Animal 53 @end 54 55 @implementation Dog 56 @end 57 58 /********Cat*******/ 59 @interface Cat : Animal 60 @end 61 62 @implementation Cat 63 @end 64 65 int main() 66 { 67 Dog *d = [Dog new]; 68 69 [d setAge:10]; 70 71 NSLog(@"age=%d", [d age]); 72 return 0; 73 }
Person *p = [Student new];
p->age = 100;
[p walk];
多态使用总结
1.没有继承就没有多态
2.代码的体现:父类类型的指针指向子类对象
3.好处:如果函数\方法参数中使用的是父类类型,可以传入父类、子类对象
4.局限性: 父类类型的变量不能直接调用子类特有的方法。必须强转为子类类型变量后,才能直接调用子类特有的方法
1 #import <Foundation/Foundation.h> 2 // 动物 3 @interface Animal : NSObject 4 - (void)eat; 5 @end 6 7 @implementation Animal 8 - (void)eat 9 { 10 NSLog(@"Animal-吃东西----"); 11 } 12 @end 13 14 // 狗 15 @interface Dog : Animal 16 - (void)run; 17 @end 18 19 @implementation Dog 20 - (void)run 21 { 22 NSLog(@"Dog---跑起来"); 23 } 24 - (void)eat 25 { 26 NSLog(@"Dog-吃东西----"); 27 } 28 @end 29 30 // 猫 31 @interface Cat : Animal 32 33 @end 34 35 @implementation Cat 36 - (void)eat 37 { 38 NSLog(@"Cat-吃东西----"); 39 } 40 @end 41 42 // 这个函数是专门用来喂动画 43 //void feed(Dog *d) 44 //{ 45 // [d eat]; 46 //} 47 // 48 //void feed2(Cat *c) 49 //{ 50 // [c eat]; 51 //} 52 // 53 54 // 如果参数中使用的是父类类型,可以传入父类、子类对象 55 void feed(Animal *a) 56 { 57 [a eat]; 58 } 59 60 int main() 61 { 62 // 多态的局限性:父类类型的变量 不能 用来调用子类的方法 63 Animal *aa = [Animal new]; 64 feed(aa); 65 66 Dog *dd = [Dog new]; 67 feed(dd); 68 69 Cat *cc = [Cat new]; 70 feed(cc); 71 72 73 // NSString *s = [Cat new]; 74 Animal *c = [Cat new]; 75 76 77 NSObject *n = [Dog new]; 78 NSObject *n2 = [Animal new]; 79 80 81 //多种形态 82 Dog *d = [Dog new]; // Dog类型 83 84 //多态:父类指针指向子类对象 85 Animal *a = [Dog new]; 86 87 // 调用方法时会检测对象的真实形象 88 [a eat]; 89 90 return 0; 91 }
NSStirng *str = @“Hello”;
NSString *name = @”mj”;
NSLog(@“我的名字是%@”, name);
1 #import <Foundation/Foundation.h> 2 3 @interface Person : NSObject 4 { 5 //char *_name; 6 NSString *_name; 7 } 8 @end 9 10 int main() 11 { 12 /* 13 // 最简单的创建字符串的方式 14 NSString *str = @"itcast"; 15 16 char *name = "itcast"; 17 18 19 NSLog(@"我在%@上课", str); 20 //NSLog(@"%s", name); 21 */ 22 23 int age = 15; 24 int no = 5; 25 NSString *name = @"哈哈jack"; 26 // length方法算的是字数 27 int size = [name length]; 28 29 NSLog(@"%d", size); 30 31 // 创建OC字符串的另一种方式 32 NSString *newStr = [NSString stringWithFormat:@"My age is %d and no is %d and name is %@", age, no, name]; 33 34 35 NSLog(@"---- %ld", [newStr length]); 36 37 return 0; 38 }
作业
1 /** 2 6.设计一个类Circle,用来表示二维平面中的圆 3 1> 属性 4 * double radius (半径) 5 * Point2D *point (圆心) 6 7 2> 方法 8 * 属性相应的set和get方法 9 * 设计一个对象方法判断跟其他圆是否相交(重叠返回YES,否则返回NO) 10 * 设计一个类方法判断两个圆是否相交(重叠返回YES,否则返回NO) 11 */ 12 #import <Foundation/Foundation.h> 13 #import <math.h> 14 15 // 点 16 @interface Point2D : NSObject 17 { 18 double _x; // x值 19 double _y; // y值 20 } 21 // x值的getter和setter 22 - (void)setX:(double)x; 23 - (double)x; 24 25 // y值的getter和setter 26 - (void)setY:(double)y; 27 - (double)y; 28 29 // 同时设置x和y 30 - (void)setX:(double)x andY:(double)y; 31 32 // 计算跟其他点的距离 33 - (double)distanceWithOther:(Point2D *)other; 34 35 // 计算两个点之间的距离 36 + (double)distanceBetweenPoint1:(Point2D *)p1 andPoint2:(Point2D *)p2; 37 @end 38 39 @implementation Point2D 40 // x值的getter和setter 41 - (void)setX:(double)x 42 { 43 _x = x; 44 } 45 - (double)x 46 { 47 return _x; 48 } 49 50 // y值的getter和setter 51 - (void)setY:(double)y 52 { 53 _y = y; 54 } 55 - (double)y 56 { 57 return _y; 58 } 59 60 // 同时设置x和y 61 - (void)setX:(double)x andY:(double)y 62 { 63 // 第1种思路 64 // _x = x; 65 // _y = y; 66 67 // 第2种思路 68 [self setX:x]; 69 [self setY:y]; 70 } 71 72 // 计算跟其他点的距离 73 - (double)distanceWithOther:(Point2D *)other 74 { 75 // 不要再傻乎乎算一遍了,直接调用类方法即可 76 return [Point2D distanceBetweenPoint1:self andPoint2:other]; 77 } 78 79 // 计算两个点之间的距离 80 + (double)distanceBetweenPoint1:(Point2D *)p1 andPoint2:(Point2D *)p2 81 { 82 // 两点距离公式:( (x1-x2)的平方 + (y1-y2)的平方 )开根 83 84 // x1-x2 85 double xDelta = [p1 x] - [p2 x]; 86 // (x1-x2)的平方 87 double xDeltaPingFang = pow(xDelta, 2); 88 89 // y1-y2 90 double yDelta = [p1 y] - [p2 y]; 91 // (y1-y2)的平方 92 double yDeltaPingFang = pow(yDelta, 2); 93 94 return sqrt(xDeltaPingFang + yDeltaPingFang); 95 } 96 @end 97 98 // 圆 99 @interface Circle : NSObject 100 { 101 double _radius; // 半径 102 Point2D *_point; // 圆心 103 } 104 105 // 半径的getter和setter 106 - (void)setRadius:(double)radius; 107 - (double)radius; 108 109 // 圆心的getter和setter 110 - (void)setPoint:(Point2D *)point; 111 - (Point2D *)point; 112 113 114 // 跟其他圆是否重叠(重叠返回YES,否则返回NO) 115 - (BOOL)isInteractWithOther:(Circle *)other; 116 // 判断两个圆是否重叠(重叠返回YES,否则返回NO) 117 + (BOOL)isInteractBetweenCircle1:(Circle *)circle1 andCircle2:(Circle *)circle2; 118 119 @end 120 121 @implementation Circle 122 // 半径的getter和setter 123 - (void)setRadius:(double)radius 124 { 125 _radius = radius; 126 } 127 - (double)radius 128 { 129 return _radius; 130 } 131 132 // 圆心的getter和setter 133 - (void)setPoint:(Point2D *)point 134 { 135 _point = point; 136 } 137 - (Point2D *)point 138 { 139 return _point; 140 } 141 142 // 跟其他圆是否重叠(重叠返回YES,否则返回NO) 143 - (BOOL)isInteractWithOther:(Circle *)other 144 { 145 return [Circle isInteractBetweenCircle1:self andCircle2:other]; 146 } 147 148 // 判断两个圆是否重叠(重叠返回YES,否则返回NO) 149 + (BOOL)isInteractBetweenCircle1:(Circle *)circle1 andCircle2:(Circle *)circle2 150 { 151 // 如果两个圆心的距离 >= 两个圆的半径和,就不重叠 152 // 如果两个圆心的距离 < 两个圆的半径和,就重叠 153 154 // 两个圆心 155 Point2D *point1 = [circle1 point]; 156 Point2D *point2 = [circle2 point]; 157 // 两个圆心的距离 158 double distance = [point1 distanceWithOther:point2]; 159 160 // 半径和 161 double radiusSum = [circle1 radius] + [circle2 radius]; 162 163 return distance < radiusSum; 164 } 165 @end 166 167 int main() 168 { 169 Circle *c1 = [Circle new]; 170 // 设置半径 171 [c1 setRadius:2]; 172 // 设置圆心 173 Point2D *p1 = [Point2D new]; 174 [p1 setX:10 andY:10]; 175 [c1 setPoint:p1]; 176 177 Circle *c2 = [Circle new]; 178 // 设置半径 179 [c2 setRadius:2]; 180 // 设置圆心 181 Point2D *p2 = [Point2D new]; 182 [p2 setX:13 andY:14]; 183 [c2 setPoint:p2]; 184 185 // 圆心距离是5 半径和是4 所以不重叠 186 BOOL b1 = [c1 isInteractWithOther:c2]; 187 188 BOOL b2 = [Circle isInteractBetweenCircle1:c1 andCircle2:c2]; 189 190 NSLog(@"%d %d", b1, b2); 191 192 return 0; 193 }